diff --git a/.gitignore b/.gitignore index 9ddba7b27..958b54730 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,5 @@ libpcre/.deps/ libpcre/pcre-config libpcre/stamp-h1 ndiff/INSTALLED_FILES +libz/contrib/vstudio/vc11/Debug_lib/ +libz/contrib/vstudio/vc11/Release_lib/ diff --git a/CHANGELOG b/CHANGELOG index 906b38c43..d6629b18a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ # Nmap Changelog ($Id$); -*-text-*- +o [GH#910] added libssh2 support, ssh-brute, ssh-run, ssh-auth-methods, + ssh-publickey-acceptance [Evangelos Deirmentzoglou] + o [NSE] http-vuln-cve2017-8917 checks for an SQL injection vulnerability affecting Joomla! 3.7.x before 3.7.1. [Wong Wai Tuck] diff --git a/Makefile.in b/Makefile.in index 240300f48..b2f359037 100644 --- a/Makefile.in +++ b/Makefile.in @@ -30,6 +30,8 @@ CCOPT = DBGFLAGS = STRIP = @STRIP@ LIBPCAPDIR = @libpcapdir@ +LIBSSH2DIR = @LIBSSH2DIR@ +ZLIBDIR = @ZLIBDIR@ LIBPCREDIR = @LIBPCREDIR@ export LIBDNETDIR = @LIBDNETDIR@ ZENMAPDIR = @ZENMAPDIR@ @@ -50,8 +52,10 @@ CPPFLAGS = @CPPFLAGS@ $(DEFS) CFLAGS = @CFLAGS@ $(DBGFLAGS) $(CCOPT) STATIC = LDFLAGS = @LDFLAGS@ $(DBGFLAGS) $(STATIC) -LIBS = @LIBNSOCK_LIBS@ @LIBNBASE_LIBS@ @LIBPCRE_LIBS@ @LIBPCAP_LIBS@ $(OPENSSL_LIBS) libnetutil/libnetutil.a @LIBDNET_LIBS@ @LIBLUA_LIBS@ @LIBLINEAR_LIBS@ @LIBS@ +LIBS = @LIBNSOCK_LIBS@ @LIBNBASE_LIBS@ @LIBPCRE_LIBS@ @LIBPCAP_LIBS@ $(OPENSSL_LIBS) $(LIBSSH2_LIBS) $(ZLIB_LIBS) libnetutil/libnetutil.a @LIBDNET_LIBS@ @LIBLUA_LIBS@ @LIBLINEAR_LIBS@ @LIBS@ OPENSSL_LIBS = @OPENSSL_LIBS@ +LIBSSH2_LIBS = @LIBSSH2_LIBS@ +ZLIB_LIBS = @ZLIB_LIBS@ # LIBS = -lefence @LIBS@ # LIBS = -lrmalloc @LIBS@ INSTALL = @INSTALL@ @@ -96,6 +100,11 @@ NSE_SRC+=nse_openssl.cc nse_ssl_cert.cc NSE_HDRS+=nse_openssl.h nse_ssl_cert.h NSE_OBJS+=nse_openssl.o nse_ssl_cert.o endif +ifneq (@LIBSSH2_LIBS@,) +NSE_SRC+=nse_libssh2.cc +NSE_HDRS+=nse_libssh2.h +NSE_OBJS+=nse_libssh2.o +endif endif export SRCS = charpool.cc FingerPrintResults.cc FPEngine.cc FPModel.cc idle_scan.cc MACLookup.cc main.cc nmap.cc nmap_dns.cc nmap_error.cc nmap_ftp.cc NmapOps.cc NmapOutputTable.cc nmap_tty.cc osscan2.cc osscan.cc output.cc payload.cc portlist.cc portreasons.cc protocols.cc scan_engine.cc scan_engine_connect.cc scan_engine_raw.cc scan_lists.cc service_scan.cc services.cc Target.cc TargetGroup.cc targets.cc tcpip.cc timing.cc traceroute.cc utils.cc xml.cc $(NSE_SRC) @@ -115,7 +124,7 @@ FPModel.o: CXXFLAGS += -g0 all: $(TARGET) $(BUILDZENMAP) $(BUILDNDIFF) $(BUILDNPING) $(BUILDNCAT) @NMAP_UPDATE_BUILD@ -$(TARGET): build-netutil @LIBLINEAR_BUILD@ @PCAP_BUILD@ @PCRE_BUILD@ @NSOCK_BUILD@ @NBASE_BUILD@ @DNET_BUILD@ @LUA_BUILD@ \ +$(TARGET): build-netutil @LIBLINEAR_BUILD@ @PCAP_BUILD@ @LIBSSH2_BUILD@ @ZLIB_BUILD@ @PCRE_BUILD@ @NSOCK_BUILD@ @NBASE_BUILD@ @DNET_BUILD@ @LUA_BUILD@ \ $(OBJS) main.o @echo Compiling nmap rm -f $@ @@ -130,6 +139,13 @@ build-dnet: $(LIBDNETDIR)/Makefile build-pcap: $(LIBPCAPDIR)/Makefile @echo Compiling libpcap; cd $(LIBPCAPDIR) && $(MAKE) +build-libssh2: $(LIBSSH2DIR)/src/Makefile + @echo Compiling libssh2; cd $(LIBSSH2DIR)/src && $(MAKE); + cd $(LIBSSH2DIR)/src && $(MAKE) prefix=$(NDIR)/$(LIBSSH2DIR) install-libLTLIBRARIES; + +build-zlib: $(ZLIBDIR)/Makefile + @echo Compiling zlib; cd $(ZLIBDIR) && $(MAKE); + build-nbase: $(NBASEDIR)/Makefile @echo Compiling libnbase; cd $(NBASEDIR) && $(MAKE) @@ -182,7 +198,7 @@ release-rpms: web: cd $(NMAPDEVDIR) && $(MAKE) web -clean: @LUA_CLEAN@ @LIBLINEAR_CLEAN@ @PCAP_CLEAN@ @PCRE_CLEAN@ @DNET_CLEAN@ \ +clean: @LUA_CLEAN@ @LIBLINEAR_CLEAN@ @PCAP_CLEAN@ @PCRE_CLEAN@ @DNET_CLEAN@ @LIBSSH2_CLEAN@ @ZLIB_CLEAN@\ clean-nsock clean-nbase clean-netutil @NPING_CLEAN@ @ZENMAP_CLEAN@ \ @NCAT_CLEAN@ @NMAP_UPDATE_CLEAN@ @NDIFF_CLEAN@ clean-tests rm -f $(OBJS) main.o $(TARGET) @@ -193,8 +209,8 @@ clean-nsock clean-nbase clean-netutil @NPING_CLEAN@ @ZENMAP_CLEAN@ \ debugclean: rm -f *.gcov *.gcda *.gcno gmon.out -distclean: @LUA_DIST_CLEAN@ @LIBLINEAR_DIST_CLEAN@ @PCAP_DIST_CLEAN@ \ -@PCRE_DIST_CLEAN@ @DNET_DIST_CLEAN@ @NPING_DIST_CLEAN@ @ZENMAP_DIST_CLEAN@ \ +distclean: @LUA_DIST_CLEAN@ @LIBLINEAR_DIST_CLEAN@ @PCAP_DIST_CLEAN@ @LIBSSH2_DIST_CLEAN@\ +@ZLIB_DIST_CLEAN@ @PCRE_DIST_CLEAN@ @DNET_DIST_CLEAN@ @NPING_DIST_CLEAN@ @ZENMAP_DIST_CLEAN@ \ @NCAT_DIST_CLEAN@ @NMAP_UPDATE_DIST_CLEAN@ distclean-netutil \ distclean-nsock distclean-nbase @NDIFF_DIST_CLEAN@ clean debugclean rm -f Makefile Makefile.bak makefile.dep nmap_config.h stamp-h \ @@ -203,6 +219,14 @@ distclean-nsock distclean-nbase @NDIFF_DIST_CLEAN@ clean debugclean clean-pcap: -cd $(LIBPCAPDIR) && $(MAKE) clean +clean-libssh2: + -cd $(LIBSSH2DIR)/src && $(MAKE) prefix=$(NDIR)/$(LIBSSH2DIR) uninstall-libLTLIBRARIES + -cd $(LIBSSH2DIR)/src && $(MAKE) prefix=$(NDIR)/$(LIBSSH2DIR) clean + -cd $(LIBSSH2DIR) && $(MAKE) clean + +clean-zlib: + -cd $(ZLIBDIR) && $(MAKE) clean + clean-pcre: -cd $(LIBPCREDIR) && $(MAKE) clean @@ -245,6 +269,13 @@ clean-tests: distclean-pcap: -cd $(LIBPCAPDIR) && $(MAKE) distclean +distclean-libssh2: + -cd $(LIBSSH2DIR)/src && $(MAKE) prefix=$(NDIR)/$(LIBSSH2DIR) distclean + -cd $(LIBSSH2DIR) && $(MAKE) distclean + +distclean-zlib: + -cd $(ZLIBDIR) && $(MAKE) distclean + distclean-pcre: -cd $(LIBPCREDIR) && $(MAKE) distclean diff --git a/configure b/configure index 6bd1ab6a5..81f010095 100755 --- a/configure +++ b/configure @@ -658,6 +658,14 @@ DNET_CLEAN DNET_BUILD LIBDNETDIR LIBDNET_LIBS +ZLIB_LIBS +ZLIB_DIST_CLEAN +ZLIB_CLEAN +ZLIB_BUILD +LIBSSH2_LIBS +LIBSSH2_DIST_CLEAN +LIBSSH2_CLEAN +LIBSSH2_BUILD PCRE_DIST_CLEAN PCRE_CLEAN PCRE_BUILD @@ -727,6 +735,8 @@ build_vendor build_cpu build pcredir +ZLIBDIR +LIBSSH2DIR libpcapdir USE_NLS target_alias @@ -748,6 +758,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -778,6 +789,8 @@ with_nping with_openssl with_libpcap with_libpcre +with_libssh2 +with_libz with_libdnet with_liblua with_liblinear @@ -804,6 +817,8 @@ PYTHON' ac_subdirs_all='nping libpcap libpcre +libssh2 +libz libdnet-stripped nbase nsock/src @@ -846,6 +861,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1098,6 +1114,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1235,7 +1260,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1388,6 +1413,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1436,6 +1462,11 @@ Optional Packages: --with-libpcre=DIR Use an existing (compiled) pcre lib from DIR/include and DIR/lib. --with-libpcre=included Always use the version included with Nmap + --with-libssh2=DIR Use specific copy of libssh2 + --with-libssh2=included Always use version included with Nmap + --without-libssh2 Compile without libssh2 + --with-libz=DIR Use specific copy of libz + --with-libz=included Always use version included with Nmap --with-libdnet=DIR Use an existing (compiled) dnet lib from DIR/include and DIR/lib. This is NOT RECOMMENDED because we have made many important fixes to our included libdnet, @@ -2433,6 +2464,12 @@ fi libpcapdir=libpcap +LIBSSH2DIR=libssh2 + + +ZLIBDIR=libz + + pcredir=libpcre @@ -5889,6 +5926,7 @@ if test "${with_openssl+set}" = set; then : ;; *) specialssldir="$with_openssl" + ac_configure_args="$ac_configure_args '--with-libssl-prefix=$with_openssl'" CPPFLAGS="$CPPFLAGS -I$with_openssl/include" LDFLAGS="$LDFLAGS -L$with_openssl/lib" ;; @@ -6553,6 +6591,384 @@ fi + +# We test whether desired libssh2 is specified explicitly + + +use_libssh2="yes" +have_libssh2="no" +test "${with_libssh2+set}" != "set" && with_libssh2="yes" + + +# Check whether --with-libssh2 was given. +if test "${with_libssh2+set}" = set; then : + withval=$with_libssh2; case "$with_libssh2" in + yes) + ac_fn_c_check_header_mongrel "$LINENO" "libssh2.h" "ac_cv_header_libssh2_h" "$ac_includes_default" +if test "x$ac_cv_header_libssh2_h" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libssh2_version in -lssh2" >&5 +$as_echo_n "checking for libssh2_version in -lssh2... " >&6; } +if ${ac_cv_lib_ssh2_libssh2_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lssh2 -lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char libssh2_version (); +int +main () +{ +return libssh2_version (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ssh2_libssh2_version=yes +else + ac_cv_lib_ssh2_libssh2_version=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssh2_libssh2_version" >&5 +$as_echo "$ac_cv_lib_ssh2_libssh2_version" >&6; } +if test "x$ac_cv_lib_ssh2_libssh2_version" = xyes; then : + have_libssh2="yes" +fi + + +fi + + + ;; + no) + with_libssh2="no" + use_libssh2="no" + ;; + included) + have_libssh2="no" + ;; + *) + _cppflags=$CPPFLAGS + _ldflags=$LDFLAGS + + CPPFLAGS="-I$with_libssh2/include $CPPFLAGS" + LDFLAGS="-L$with_libssh2/lib $LDFLAGS" + + ac_fn_c_check_header_compile "$LINENO" "libssh2.h" "ac_cv_header_libssh2_h" "-lm +" +if test "x$ac_cv_header_libssh2_h" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libssh2_version in -lssh2" >&5 +$as_echo_n "checking for libssh2_version in -lssh2... " >&6; } +if ${ac_cv_lib_ssh2_libssh2_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lssh2 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char libssh2_version (); +int +main () +{ +return libssh2_version (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ssh2_libssh2_version=yes +else + ac_cv_lib_ssh2_libssh2_version=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssh2_libssh2_version" >&5 +$as_echo "$ac_cv_lib_ssh2_libssh2_version" >&6; } +if test "x$ac_cv_lib_ssh2_libssh2_version" = xyes; then : + have_libssh2=yes + LIBSSH2_INC=$with_libssh2/include + LIBSSH2_LIB=$with_libssh2/lib +fi + +fi + + + + LDFLAGS=$_ldflags + CPPFLAGS=$_cppflags + with_libssh2="yes" + ;; + esac + +fi + + + +if test $use_libssh2 = yes -a $use_openssl = yes; then + trace_use="$trace_use libssh2" + + if test $have_libssh2 = yes; then + if test "${LIBSSH2_LIB+set}" = "set"; then + CPPFLAGS="-I$LIBSSH2_INC $CPPFLAGS" + LDFLAGS="-L$LIBSSH2_LIB $LDFLAGS" + fi + fi + + if test $have_libssh2 != yes; then + subdirs="$subdirs libssh2" + + + if test "${LIBSSH2_INC+set}" = "set"; then + CPPFLAGS="$CPPFLAGS -I$LIBSSH2_INC" + else + CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/$LIBSSH2DIR/include" + fi + + LIBSSH2_LIBS="$LIBSSH2DIR/lib/libssh2.a" + LIBSSH2_BUILD="build-libssh2" + LIBSSH2_CLEAN="clean-libssh2" + LIBSSH2_DIST_CLEAN="distclean-libssh2" + +$as_echo "#define LIBSSH2_INCLUDED 1" >>confdefs.h + + with_libssh2="yes" + else + LIBSSH2_LIBS="-lssh2" + LIBSSH2_BUILD="" + LIBSSH2_CLEAN="" + LIBSSH2_DIST_CLEAN="" + fi + + +$as_echo "#define HAVE_LIBSSH2 1" >>confdefs.h + +else + use_libssh2="no" + trace_no_use="$trace_no_use libssh2" + LIBSSH2_LIBS="" + LIBSSH2_BUILD="" + LIBSSH2_CLEAN="" + LIBSSH2_DIST_CLEAN="" +fi + + + + + + + +# We test whether desired libz is specified explicitly + +have_libz="no" +test "${with_libz+set}" != "set" && with_libz="no" + +# Force use of included zlib if compiling with libssh2 +if test $use_libssh2 = "yes" -a $with_libz = "no"; then + with_libz="yes" +fi + + +# Check whether --with-libz was given. +if test "${with_libz+set}" = set; then : + withval=$with_libz; + case "$with_libz" in + yes) + ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 +$as_echo_n "checking for gzread in -lz... " >&6; } +if ${ac_cv_lib_z_gzread+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gzread (); +int +main () +{ +return gzread (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_gzread=yes +else + ac_cv_lib_z_gzread=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 +$as_echo "$ac_cv_lib_z_gzread" >&6; } +if test "x$ac_cv_lib_z_gzread" = xyes; then : + have_libz="yes" +fi + + +fi + + + ;; + no) + # Do nothing + ;; + included) + with_libz="yes" + have_libz="no" + ;; + *) + _cppflags=$CPPFLAGS + _ldflags=$LDFLAGS + + CPPFLAGS="-I$with_libz/include $CPPFLAGS" + LDFLAGS="-L$with_libz/lib $LDFLAGS" + + ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 +$as_echo_n "checking for gzread in -lz... " >&6; } +if ${ac_cv_lib_z_gzread+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gzread (); +int +main () +{ +return gzread (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_gzread=yes +else + ac_cv_lib_z_gzread=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 +$as_echo "$ac_cv_lib_z_gzread" >&6; } +if test "x$ac_cv_lib_z_gzread" = xyes; then : + have_libz=yes + ZLIB_INC=$with_libz/include + ZLIB_LIB=$with_libz/lib +fi + + +fi + + + + LDFLAGS=$_ldflags + CPPFLAGS=$_cppflags + with_libz="yes" + ;; + esac + + +fi + + +if test $with_libz = yes -a $with_libssh2 = yes; then + trace_use="$trace_use zlib (libssh2 dependency)" + + if test $have_libz = yes; then + if test "${ZLIB_LIB+set}" = "set"; then + CPPFLAGS="-I$ZLIB_INC $CPPFLAGS" + LDFLAGS="-L$ZLIB_LIB $LDFLAGS" + fi + fi + + if test $have_libz != yes; then + subdirs="$subdirs libz" + + + if test "${ZLIB_INC+set}" = "set"; then + CPPFLAGS="$CPPFLAGS -I$ZLIB_INC" + else + CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/$ZLIBDIR" + fi + + ZLIB_LIBS="$ZLIBDIR/libz.a" + ZLIB_BUILD="build-zlib" + ZLIB_CLEAN="clean-zlib" + ZLIB_DIST_CLEAN="distclean-zlib" + +$as_echo "#define ZLIB_INCLUDED 1" >>confdefs.h + + else + ZLIB_LIBS="-lz" + ZLIB_BUILD="" + ZLIB_CLEAN="" + ZLIB_DIST_CLEAN="" + fi + +$as_echo "#define HAVE_LIBZ_V 1" >>confdefs.h + + +$as_echo "#define have_libz 1" >>confdefs.h + +else + trace_no_use="$trace_no_use zlib (libssh2 dependency)" + ZLIB_LIBS="" + ZLIB_BUILD="" + ZLIB_CLEAN="" + ZLIB_DIST_CLEAN="" +fi + + + + + + have_dnet=no requested_included_dnet=no LIBDNETDIR=libdnet-stripped @@ -9304,3 +9720,7 @@ echo "Type make (or gmake on some *BSD machines) to compile." if test "x$use_openssl" = "xno" && test "x$with_openssl" != "xno"; then echo "WARNING: You are compiling without OpenSSL" fi + +if test "x$use_libssh2" != "xyes"; then + echo "WARNING: You are compiling without LibSSH2" +fi diff --git a/configure.ac b/configure.ac index d9ffe3d4f..1b29e65ed 100644 --- a/configure.ac +++ b/configure.ac @@ -45,6 +45,12 @@ fi libpcapdir=libpcap AC_SUBST(libpcapdir) +LIBSSH2DIR=libssh2 +AC_SUBST(LIBSSH2DIR) + +ZLIBDIR=libz +AC_SUBST(ZLIBDIR) + pcredir=libpcre AC_SUBST(pcredir) @@ -349,6 +355,7 @@ AC_HELP_STRING([--with-openssl=DIR],[Use optional openssl libs and includes from ;; *) specialssldir="$with_openssl" + ac_configure_args="$ac_configure_args '--with-libssl-prefix=$with_openssl'" CPPFLAGS="$CPPFLAGS -I$with_openssl/include" LDFLAGS="$LDFLAGS -L$with_openssl/lib" ;; @@ -544,6 +551,197 @@ AC_SUBST(PCRE_BUILD) AC_SUBST(PCRE_CLEAN) AC_SUBST(PCRE_DIST_CLEAN) + +# We test whether desired libssh2 is specified explicitly + + +use_libssh2="yes" +have_libssh2="no" +test "${with_libssh2+set}" != "set" && with_libssh2="yes" + +AC_ARG_WITH(libssh2, +AC_HELP_STRING([--with-libssh2=DIR], [Use specific copy of libssh2]) +AC_HELP_STRING([--with-libssh2=included], [Always use version included with Nmap]) +AC_HELP_STRING([--without-libssh2], [Compile without libssh2]), +[ case "$with_libssh2" in + yes) + AC_CHECK_HEADER(libssh2.h,[ + AC_CHECK_LIB(ssh2, libssh2_version, + [have_libssh2="yes"],,[-lm]) + ]) + ;; + no) + with_libssh2="no" + use_libssh2="no" + ;; + included) + have_libssh2="no" + ;; + *) + _cppflags=$CPPFLAGS + _ldflags=$LDFLAGS + + CPPFLAGS="-I$with_libssh2/include $CPPFLAGS" + LDFLAGS="-L$with_libssh2/lib $LDFLAGS" + + AC_CHECK_HEADER(libssh2.h,[ + AC_CHECK_LIB(ssh2, libssh2_version, + [have_libssh2=yes + LIBSSH2_INC=$with_libssh2/include + LIBSSH2_LIB=$with_libssh2/lib])],,[-lm]) + + LDFLAGS=$_ldflags + CPPFLAGS=$_cppflags + with_libssh2="yes" + ;; + esac] +) + + +if test $use_libssh2 = yes -a $use_openssl = yes; then + trace_use="$trace_use libssh2" + + if test $have_libssh2 = yes; then + if test "${LIBSSH2_LIB+set}" = "set"; then + CPPFLAGS="-I$LIBSSH2_INC $CPPFLAGS" + LDFLAGS="-L$LIBSSH2_LIB $LDFLAGS" + fi + fi + + if test $have_libssh2 != yes; then + AC_CONFIG_SUBDIRS(libssh2) + + if test "${LIBSSH2_INC+set}" = "set"; then + CPPFLAGS="$CPPFLAGS -I$LIBSSH2_INC" + else + CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/$LIBSSH2DIR/include" + fi + + LIBSSH2_LIBS="$LIBSSH2DIR/lib/libssh2.a" + LIBSSH2_BUILD="build-libssh2" + LIBSSH2_CLEAN="clean-libssh2" + LIBSSH2_DIST_CLEAN="distclean-libssh2" + AC_DEFINE(LIBSSH2_INCLUDED, 1, [Using included libssh2]) + with_libssh2="yes" + else + LIBSSH2_LIBS="-lssh2" + LIBSSH2_BUILD="" + LIBSSH2_CLEAN="" + LIBSSH2_DIST_CLEAN="" + fi + + AC_DEFINE(HAVE_LIBSSH2, 1, [Have libssh2 library]) +else + use_libssh2="no" + trace_no_use="$trace_no_use libssh2" + LIBSSH2_LIBS="" + LIBSSH2_BUILD="" + LIBSSH2_CLEAN="" + LIBSSH2_DIST_CLEAN="" +fi + +AC_SUBST(LIBSSH2_BUILD) +AC_SUBST(LIBSSH2_CLEAN) +AC_SUBST(LIBSSH2_DIST_CLEAN) +AC_SUBST(LIBSSH2_LIBS) + + +# We test whether desired libz is specified explicitly + +have_libz="no" +test "${with_libz+set}" != "set" && with_libz="no" + +# Force use of included zlib if compiling with libssh2 +if test $use_libssh2 = "yes" -a $with_libz = "no"; then + with_libz="yes" +fi + +AC_ARG_WITH(libz, +AC_HELP_STRING([--with-libz=DIR], [Use specific copy of libz]) +AC_HELP_STRING([--with-libz=included], [Always use version included with Nmap]), +[ + case "$with_libz" in + yes) + AC_CHECK_HEADER(zlib.h,[ + AC_CHECK_LIB(z, gzread, + [have_libz="yes"],,) + ]) + ;; + no) + # Do nothing + ;; + included) + with_libz="yes" + have_libz="no" + ;; + *) + _cppflags=$CPPFLAGS + _ldflags=$LDFLAGS + + CPPFLAGS="-I$with_libz/include $CPPFLAGS" + LDFLAGS="-L$with_libz/lib $LDFLAGS" + + AC_CHECK_HEADER(zlib.h,[ + AC_CHECK_LIB(z, gzread, + [have_libz=yes + ZLIB_INC=$with_libz/include + ZLIB_LIB=$with_libz/lib]) + ],, + ) + + LDFLAGS=$_ldflags + CPPFLAGS=$_cppflags + with_libz="yes" + ;; + esac +] +) + +if test $with_libz = yes -a $with_libssh2 = yes; then + trace_use="$trace_use zlib (libssh2 dependency)" + + if test $have_libz = yes; then + if test "${ZLIB_LIB+set}" = "set"; then + CPPFLAGS="-I$ZLIB_INC $CPPFLAGS" + LDFLAGS="-L$ZLIB_LIB $LDFLAGS" + fi + fi + + if test $have_libz != yes; then + AC_CONFIG_SUBDIRS(libz) + + if test "${ZLIB_INC+set}" = "set"; then + CPPFLAGS="$CPPFLAGS -I$ZLIB_INC" + else + CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/$ZLIBDIR" + fi + + ZLIB_LIBS="$ZLIBDIR/libz.a" + ZLIB_BUILD="build-zlib" + ZLIB_CLEAN="clean-zlib" + ZLIB_DIST_CLEAN="distclean-zlib" + AC_DEFINE(ZLIB_INCLUDED, 1, [Using included zlib]) + else + ZLIB_LIBS="-lz" + ZLIB_BUILD="" + ZLIB_CLEAN="" + ZLIB_DIST_CLEAN="" + fi + AC_DEFINE(HAVE_LIBZ_V, 1, [Have zlib library for versioning]) + AC_DEFINE(have_libz, 1, [Have zlib library]) +else + trace_no_use="$trace_no_use zlib (libssh2 dependency)" + ZLIB_LIBS="" + ZLIB_BUILD="" + ZLIB_CLEAN="" + ZLIB_DIST_CLEAN="" +fi + +AC_SUBST(ZLIB_BUILD) +AC_SUBST(ZLIB_CLEAN) +AC_SUBST(ZLIB_DIST_CLEAN) +AC_SUBST(ZLIB_LIBS) + have_dnet=no requested_included_dnet=no LIBDNETDIR=libdnet-stripped @@ -1007,3 +1205,7 @@ echo "Type make (or gmake on some *BSD machines) to compile." if test "x$use_openssl" = "xno" && test "x$with_openssl" != "xno"; then echo "WARNING: You are compiling without OpenSSL" fi + +if test "x$use_libssh2" != "xyes"; then + echo "WARNING: You are compiling without LibSSH2" +fi diff --git a/libssh2/CMakeLists.txt b/libssh2/CMakeLists.txt new file mode 100644 index 000000000..ae5594289 --- /dev/null +++ b/libssh2/CMakeLists.txt @@ -0,0 +1,109 @@ +# Copyright (c) 2014, 2015 Alexander Lamaison +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided +# that the following conditions are met: +# +# Redistributions of source code must retain the above +# copyright notice, this list of conditions and the +# following disclaimer. +# +# 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. +# +# Neither the name of the copyright holder nor the names +# of any other contributors may be used to endorse or +# promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +cmake_minimum_required(VERSION 2.8.11) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +project(libssh2 C) +set(PROJECT_URL "https://www.libssh2.org/") +set(PROJECT_DESCRIPTION "The SSH library") + +if (CMAKE_VERSION VERSION_LESS "3.1") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + set (CMAKE_C_FLAGS "--std=gnu90 ${CMAKE_C_FLAGS}") + endif() +else() + set (CMAKE_C_STANDARD 90) +endif() + +option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF) + +# Parse version + +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/include/libssh2.h _HEADER_CONTENTS) +string( + REGEX REPLACE ".*#define LIBSSH2_VERSION[ \t]+\"([^\"]+)\".*" "\\1" + LIBSSH2_VERSION "${_HEADER_CONTENTS}") +string( + REGEX REPLACE ".*#define LIBSSH2_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" + LIBSSH2_VERSION_MAJOR "${_HEADER_CONTENTS}") +string( + REGEX REPLACE ".*#define LIBSSH2_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" + LIBSSH2_VERSION_MINOR "${_HEADER_CONTENTS}") +string( + REGEX REPLACE ".*#define LIBSSH2_VERSION_PATCH[ \t]+([0-9]+).*" "\\1" + LIBSSH2_VERSION_PATCH "${_HEADER_CONTENTS}") + +if(NOT LIBSSH2_VERSION OR + NOT LIBSSH2_VERSION_MAJOR MATCHES "^[0-9]+$" OR + NOT LIBSSH2_VERSION_MINOR MATCHES "^[0-9]+$" OR + NOT LIBSSH2_VERSION_PATCH MATCHES "^[0-9]+$") + message( + FATAL_ERROR + "Unable to parse version from" + "${CMAKE_CURRENT_SOURCE_DIR}/include/libssh2.h") +endif() + +include(GNUInstallDirs) +install( + FILES docs/AUTHORS COPYING docs/HACKING README RELEASE-NOTES NEWS + DESTINATION ${CMAKE_INSTALL_DOCDIR}) + +include(max_warnings) +include(FeatureSummary) + +add_subdirectory(src) + +option(BUILD_EXAMPLES "Build libssh2 examples" ON) +if(BUILD_EXAMPLES) + add_subdirectory(example) +endif() + +option(BUILD_TESTING "Build libssh2 test suite" ON) +if(BUILD_TESTING) + enable_testing() + add_subdirectory(tests) +endif() + +add_subdirectory(docs) + +feature_summary(WHAT ALL) + +set(CPACK_PACKAGE_VERSION_MAJOR ${LIBSSH2_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${LIBSSH2_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${LIBSSH2_VERSION_PATCH}) +set(CPACK_PACKAGE_VERSION ${LIBSSH2_VERSION}) +include(CPack) diff --git a/libssh2/COPYING b/libssh2/COPYING new file mode 100644 index 000000000..f2ca94772 --- /dev/null +++ b/libssh2/COPYING @@ -0,0 +1,42 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2005,2006 Mikhail Gusarov + * Copyright (c) 2006-2007 The Written Word, Inc. + * Copyright (c) 2007 Eli Fant + * Copyright (c) 2009-2014 Daniel Stenberg + * Copyright (C) 2008, 2009 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + diff --git a/libssh2/ChangeLog b/libssh2/ChangeLog new file mode 100644 index 000000000..404c887c2 --- /dev/null +++ b/libssh2/ChangeLog @@ -0,0 +1 @@ +see NEWS diff --git a/libssh2/Makefile.OpenSSL.inc b/libssh2/Makefile.OpenSSL.inc new file mode 100644 index 000000000..76f3e85ca --- /dev/null +++ b/libssh2/Makefile.OpenSSL.inc @@ -0,0 +1,2 @@ +CRYPTO_CSOURCES = openssl.c +CRYPTO_HHEADERS = openssl.h diff --git a/libssh2/Makefile.WinCNG.inc b/libssh2/Makefile.WinCNG.inc new file mode 100644 index 000000000..c18350eed --- /dev/null +++ b/libssh2/Makefile.WinCNG.inc @@ -0,0 +1,2 @@ +CRYPTO_CSOURCES = wincng.c +CRYPTO_HHEADERS = wincng.h diff --git a/libssh2/Makefile.am b/libssh2/Makefile.am new file mode 100644 index 000000000..07eb81bc4 --- /dev/null +++ b/libssh2/Makefile.am @@ -0,0 +1,150 @@ +AUTOMAKE_OPTIONS = foreign nostdinc + +SUBDIRS = src +#SUBDIRS = src tests docs +#if BUILD_EXAMPLES +#SUBDIRS += example +#endif + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libssh2.pc + +include_HEADERS = \ + include/libssh2.h \ + include/libssh2_publickey.h \ + include/libssh2_sftp.h + +NETWAREFILES = nw/keepscreen.c \ + nw/nwlib.c \ + nw/GNUmakefile \ + nw/test/GNUmakefile + +DSP = win32/libssh2.dsp +VCPROJ = win32/libssh2.vcproj + +DISTCLEANFILES = $(DSP) + +VMSFILES = vms/libssh2_make_example.dcl vms/libssh2_make_help.dcl \ +vms/libssh2_make_kit.dcl vms/libssh2_make_lib.dcl vms/man2help.c \ +vms/readme.vms vms/libssh2_config.h + +WIN32FILES = win32/GNUmakefile win32/test/GNUmakefile \ +win32/libssh2_config.h win32/config.mk win32/rules.mk \ +win32/Makefile.Watcom win32/libssh2.dsw win32/tests.dsp $(DSP) \ +win32/msvcproj.head win32/msvcproj.foot win32/libssh2.rc + +OS400FILES = os400/README400 os400/initscript.sh os400/make.sh \ +os400/make-src.sh os400/make-rpg.sh os400/make-include.sh \ +os400/os400sys.c os400/ccsid.c \ +os400/libssh2_config.h os400/macros.h os400/libssh2_ccsid.h \ +os400/include/alloca.h os400/include/sys/socket.h os400/include/stdio.h \ +os400/libssh2rpg/libssh2.rpgle.in \ +os400/libssh2rpg/libssh2_ccsid.rpgle.in \ +os400/libssh2rpg/libssh2_publickey.rpgle \ +os400/libssh2rpg/libssh2_sftp.rpgle \ +Makefile.os400qc3.inc + +EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk \ + maketgz NMakefile RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath \ + CMakeLists.txt cmake $(OS400FILES) + +ACLOCAL_AMFLAGS = -I m4 + +.PHONY: ChangeLog +ChangeLog: + echo "see NEWS" > ./ChangeLog +DISTCLEANFILES += ChangeLog + +dist-hook: + rm -rf $(top_builddir)/tests/log + find $(distdir) -name "*.dist" -exec rm {} \; + (distit=`find $(srcdir) -name "*.dist"`; \ + for file in $$distit; do \ + strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \ + cp $$file $(distdir)$$strip; \ + done) + +# Code Coverage + +init-coverage: + make clean + lcov --directory . --zerocounters + +COVERAGE_CCOPTS ?= "-g --coverage" +COVERAGE_OUT ?= docs/coverage + +build-coverage: + make CFLAGS=$(COVERAGE_CCOPTS) check + mkdir -p $(COVERAGE_OUT) + lcov --directory . --output-file $(COVERAGE_OUT)/$(PACKAGE).info \ + --capture + +gen-coverage: + genhtml --output-directory $(COVERAGE_OUT) \ + $(COVERAGE_OUT)/$(PACKAGE).info \ + --highlight --frames --legend \ + --title "$(PACKAGE_NAME)" + +coverage: init-coverage build-coverage gen-coverage + +# DSP/VCPROJ generation adapted from libcurl +# only OpenSSL and WinCNG are supported with this build system +CRYPTO_CSOURCES = openssl.c wincng.c mbedtls.c +CRYPTO_HHEADERS = openssl.h wincng.h mbedtls.h +# Makefile.inc provides the CSOURCES and HHEADERS defines +include Makefile.inc + +WIN32SOURCES = $(CSOURCES) +WIN32HEADERS = $(HHEADERS) libssh2_config.h + +$(DSP): win32/msvcproj.head win32/msvcproj.foot Makefile.am + echo "creating $(DSP)" + @( (cat $(srcdir)/win32/msvcproj.head; \ + echo "# Begin Group \"Source Files\""; \ + echo ""; \ + echo "# PROP Default_Filter \"cpp;c;cxx\""; \ + win32_srcs='$(WIN32SOURCES)'; \ + sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \ + for file in $$sorted_srcs; do \ + echo "# Begin Source File"; \ + echo ""; \ + echo "SOURCE=..\\src\\"$$file; \ + echo "# End Source File"; \ + done; \ + echo "# End Group"; \ + echo "# Begin Group \"Header Files\""; \ + echo ""; \ + echo "# PROP Default_Filter \"h;hpp;hxx\""; \ + win32_hdrs='$(WIN32HEADERS)'; \ + sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \ + for file in $$sorted_hdrs; do \ + echo "# Begin Source File"; \ + echo ""; \ + if [ "$$file" == "libssh2_config.h" ]; \ + then \ + echo "SOURCE=.\\"$$file; \ + else \ + echo "SOURCE=..\\src\\"$$file; \ + fi; \ + echo "# End Source File"; \ + done; \ + echo "# End Group"; \ + cat $(srcdir)/win32/msvcproj.foot) | \ + awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ ) + +$(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am + echo "creating $(VCPROJ)" + @( (cat $(srcdir)/vc8proj.head; \ + win32_srcs='$(WIN32SOURCES)'; \ + sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \ + for file in $$sorted_srcs; do \ + echo ""; \ + done; \ + echo ""; \ + win32_hdrs='$(WIN32HEADERS)'; \ + sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \ + for file in $$sorted_hdrs; do \ + echo ""; \ + done; \ + cat $(srcdir)/vc8proj.foot) | \ + awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ ) diff --git a/libssh2/Makefile.in b/libssh2/Makefile.in new file mode 100644 index 000000000..4577a04a0 --- /dev/null +++ b/libssh2/Makefile.in @@ -0,0 +1,1057 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(include_HEADERS) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h \ + $(top_builddir)/example/libssh2_config.h +CONFIG_CLEAN_FILES = libssh2.pc +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(includedir)" +DATA = $(pkgconfig_DATA) +HEADERS = $(include_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \ + $(srcdir)/libssh2.pc.in COPYING ChangeLog NEWS README compile \ + config.guess config.rpath config.sub depcomp install-sh \ + ltmain.sh missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@ +HAVE_LIBCRYPT32 = @HAVE_LIBCRYPT32@ +HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@ +HAVE_LIBMBEDTLS = @HAVE_LIBMBEDTLS@ +HAVE_LIBSSL = @HAVE_LIBSSL@ +HAVE_LIBZ = @HAVE_LIBZ@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBBCRYPT = @LIBBCRYPT@ +LIBBCRYPT_PREFIX = @LIBBCRYPT_PREFIX@ +LIBCRYPT32 = @LIBCRYPT32@ +LIBCRYPT32_PREFIX = @LIBCRYPT32_PREFIX@ +LIBGCRYPT = @LIBGCRYPT@ +LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@ +LIBMBEDTLS = @LIBMBEDTLS@ +LIBMBEDTLS_PREFIX = @LIBMBEDTLS_PREFIX@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSREQUIRED = @LIBSREQUIRED@ +LIBSSH2VER = @LIBSSH2VER@ +LIBSSL = @LIBSSL@ +LIBSSL_PREFIX = @LIBSSL_PREFIX@ +LIBTOOL = @LIBTOOL@ +LIBZ = @LIBZ@ +LIBZ_PREFIX = @LIBZ_PREFIX@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBBCRYPT = @LTLIBBCRYPT@ +LTLIBCRYPT32 = @LTLIBCRYPT32@ +LTLIBGCRYPT = @LTLIBGCRYPT@ +LTLIBMBEDTLS = @LTLIBMBEDTLS@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBSSL = @LTLIBSSL@ +LTLIBZ = @LTLIBZ@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SSHD = @SSHD@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign nostdinc +SUBDIRS = src +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libssh2.pc +include_HEADERS = \ + include/libssh2.h \ + include/libssh2_publickey.h \ + include/libssh2_sftp.h + +NETWAREFILES = nw/keepscreen.c \ + nw/nwlib.c \ + nw/GNUmakefile \ + nw/test/GNUmakefile + +DSP = win32/libssh2.dsp +VCPROJ = win32/libssh2.vcproj +DISTCLEANFILES = $(DSP) ChangeLog +VMSFILES = vms/libssh2_make_example.dcl vms/libssh2_make_help.dcl \ +vms/libssh2_make_kit.dcl vms/libssh2_make_lib.dcl vms/man2help.c \ +vms/readme.vms vms/libssh2_config.h + +WIN32FILES = win32/GNUmakefile win32/test/GNUmakefile \ +win32/libssh2_config.h win32/config.mk win32/rules.mk \ +win32/Makefile.Watcom win32/libssh2.dsw win32/tests.dsp $(DSP) \ +win32/msvcproj.head win32/msvcproj.foot win32/libssh2.rc + +OS400FILES = os400/README400 os400/initscript.sh os400/make.sh \ +os400/make-src.sh os400/make-rpg.sh os400/make-include.sh \ +os400/os400sys.c os400/ccsid.c \ +os400/libssh2_config.h os400/macros.h os400/libssh2_ccsid.h \ +os400/include/alloca.h os400/include/sys/socket.h os400/include/stdio.h \ +os400/libssh2rpg/libssh2.rpgle.in \ +os400/libssh2rpg/libssh2_ccsid.rpgle.in \ +os400/libssh2rpg/libssh2_publickey.rpgle \ +os400/libssh2rpg/libssh2_sftp.rpgle \ +Makefile.os400qc3.inc + +EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk \ + maketgz NMakefile RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath \ + CMakeLists.txt cmake $(OS400FILES) + +ACLOCAL_AMFLAGS = -I m4 + +# DSP/VCPROJ generation adapted from libcurl +# only OpenSSL and WinCNG are supported with this build system +CRYPTO_CSOURCES = openssl.c wincng.c mbedtls.c +CRYPTO_HHEADERS = openssl.h wincng.h mbedtls.h +CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \ + packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \ + version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c + +HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \ + mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h + +# Makefile.inc provides the CSOURCES and HHEADERS defines +WIN32SOURCES = $(CSOURCES) +WIN32HEADERS = $(HHEADERS) libssh2_config.h +all: all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; +$(srcdir)/Makefile.inc $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +libssh2.pc: $(top_builddir)/config.status $(srcdir)/libssh2.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-includeHEADERS install-pkgconfigDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-includeHEADERS uninstall-pkgconfigDATA + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-generic distclean-libtool distclean-tags \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am \ + install-includeHEADERS install-info install-info-am \ + install-man install-pdf install-pdf-am install-pkgconfigDATA \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-includeHEADERS uninstall-pkgconfigDATA + +.PRECIOUS: Makefile + + +.PHONY: ChangeLog +ChangeLog: + echo "see NEWS" > ./ChangeLog + +dist-hook: + rm -rf $(top_builddir)/tests/log + find $(distdir) -name "*.dist" -exec rm {} \; + (distit=`find $(srcdir) -name "*.dist"`; \ + for file in $$distit; do \ + strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \ + cp $$file $(distdir)$$strip; \ + done) + +# Code Coverage + +init-coverage: + make clean + lcov --directory . --zerocounters + +COVERAGE_CCOPTS ?= "-g --coverage" +COVERAGE_OUT ?= docs/coverage + +build-coverage: + make CFLAGS=$(COVERAGE_CCOPTS) check + mkdir -p $(COVERAGE_OUT) + lcov --directory . --output-file $(COVERAGE_OUT)/$(PACKAGE).info \ + --capture + +gen-coverage: + genhtml --output-directory $(COVERAGE_OUT) \ + $(COVERAGE_OUT)/$(PACKAGE).info \ + --highlight --frames --legend \ + --title "$(PACKAGE_NAME)" + +coverage: init-coverage build-coverage gen-coverage + +$(DSP): win32/msvcproj.head win32/msvcproj.foot Makefile.am + echo "creating $(DSP)" + @( (cat $(srcdir)/win32/msvcproj.head; \ + echo "# Begin Group \"Source Files\""; \ + echo ""; \ + echo "# PROP Default_Filter \"cpp;c;cxx\""; \ + win32_srcs='$(WIN32SOURCES)'; \ + sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \ + for file in $$sorted_srcs; do \ + echo "# Begin Source File"; \ + echo ""; \ + echo "SOURCE=..\\src\\"$$file; \ + echo "# End Source File"; \ + done; \ + echo "# End Group"; \ + echo "# Begin Group \"Header Files\""; \ + echo ""; \ + echo "# PROP Default_Filter \"h;hpp;hxx\""; \ + win32_hdrs='$(WIN32HEADERS)'; \ + sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \ + for file in $$sorted_hdrs; do \ + echo "# Begin Source File"; \ + echo ""; \ + if [ "$$file" == "libssh2_config.h" ]; \ + then \ + echo "SOURCE=.\\"$$file; \ + else \ + echo "SOURCE=..\\src\\"$$file; \ + fi; \ + echo "# End Source File"; \ + done; \ + echo "# End Group"; \ + cat $(srcdir)/win32/msvcproj.foot) | \ + awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ ) + +$(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am + echo "creating $(VCPROJ)" + @( (cat $(srcdir)/vc8proj.head; \ + win32_srcs='$(WIN32SOURCES)'; \ + sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \ + for file in $$sorted_srcs; do \ + echo ""; \ + done; \ + echo ""; \ + win32_hdrs='$(WIN32HEADERS)'; \ + sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \ + for file in $$sorted_hdrs; do \ + echo ""; \ + done; \ + cat $(srcdir)/vc8proj.foot) | \ + awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ ) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libssh2/Makefile.inc b/libssh2/Makefile.inc new file mode 100644 index 000000000..8f2e570cb --- /dev/null +++ b/libssh2/Makefile.inc @@ -0,0 +1,6 @@ +CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \ + packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \ + version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c + +HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \ + mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h diff --git a/libssh2/Makefile.libgcrypt.inc b/libssh2/Makefile.libgcrypt.inc new file mode 100644 index 000000000..5d56292ce --- /dev/null +++ b/libssh2/Makefile.libgcrypt.inc @@ -0,0 +1,2 @@ +CRYPTO_CSOURCES = libgcrypt.c +CRYPTO_HHEADERS = libgcrypt.h diff --git a/libssh2/Makefile.mbedTLS.inc b/libssh2/Makefile.mbedTLS.inc new file mode 100644 index 000000000..7e9786429 --- /dev/null +++ b/libssh2/Makefile.mbedTLS.inc @@ -0,0 +1,2 @@ +CRYPTO_CSOURCES = mbedtls.c +CRYPTO_HHEADERS = mbedtls.h diff --git a/libssh2/Makefile.os400qc3.inc b/libssh2/Makefile.os400qc3.inc new file mode 100644 index 000000000..e55094d9b --- /dev/null +++ b/libssh2/Makefile.os400qc3.inc @@ -0,0 +1,2 @@ +CRYPTO_CSOURCES = os400qc3.c +CRYPTO_HHEADERS = os400qc3.h diff --git a/libssh2/NEWS b/libssh2/NEWS new file mode 100644 index 000000000..e3caaece5 --- /dev/null +++ b/libssh2/NEWS @@ -0,0 +1,5491 @@ + Changelog for the libssh2 project. Generated with git2news.pl + +Version 1.8.0 (25 Oct 2016) + +Daniel Stenberg (25 Oct 2016) +- RELEASE-NOTES: adjusted for 1.8.0 + +Kamil Dudka (20 Oct 2016) +- Revert "aes: the init function fails when OpenSSL has AES support" + + This partially reverts commit f4f2298ef3635acd031cc2ee0e71026cdcda5864 + because it caused the compatibility code to call initialization routines + redundantly, leading to memory leakage with OpenSSL 1.1 and broken curl + test-suite in Fedora: + + 88 bytes in 1 blocks are definitely lost in loss record 5 of 8 + at 0x4C2DB8D: malloc (vg_replace_malloc.c:299) + by 0x72C607D: CRYPTO_zalloc (mem.c:100) + by 0x72A2480: EVP_CIPHER_meth_new (cmeth_lib.c:18) + by 0x4E5A550: make_ctr_evp.isra.0 (openssl.c:407) + by 0x4E5A8E8: _libssh2_init_aes_ctr (openssl.c:471) + by 0x4E5BB5A: libssh2_init (global.c:49) + +Daniel Stenberg (19 Oct 2016) +- [Charles Collicutt brought this change] + + libssh2_wait_socket: Fix comparison with api_timeout to use milliseconds (#134) + + Fixes #74 + +- [Charles Collicutt brought this change] + + Set err_msg on _libssh2_wait_socket errors (#135) + +- Revert "travis: Test mbedtls too" + + This reverts commit 3e6de50a24815e72ec5597947f1831f6083b7da8. + + Travis doesn't seem to support the mbedtls-dev package + +- maketgz: support "only" to only update version number locally + + and fix the date output locale + +- configure: make the --with-* options override the OpenSSL default + + ... previously it would default to OpenSSL even with the --with-[crypto] + options used unless you specificly disabled OpenSSL. Now, enabling another + backend will automatically disable OpenSSL if the other one is found. + +- [Keno Fischer brought this change] + + docs: Add documentation on new cmake/configure options + +- [Keno Fischer brought this change] + + configure: Add support for building with mbedtls + +- [wildart brought this change] + + travis: Test mbedtls too + +- [wildart brought this change] + + crypto: add support for the mbedTLS backend + + Closes #132 + +- [wildart brought this change] + + cmake: Add CLEAR_MEMORY option, analogously to that for autoconf + +- README.md: fix link typo + +- README: markdown version to look nicer on github + +Viktor Szakats (5 Sep 2016) +- [Taylor Holberton brought this change] + + openssl: add OpenSSL 1.1.0 compatibility + +Daniel Stenberg (4 Sep 2016) +- [Antenore Gatta brought this change] + + tests: HAVE_NETINET_IN_H was not defined correctly (#127) + + Fixes #125 + +- SECURITY: fix web site typo + +- SECURITY: security process + +GitHub (14 Aug 2016) +- [Alexander Lamaison brought this change] + + Basic dockerised test suite. + + This introduces a test suite for libssh2. It runs OpenSSH in a Docker + container because that works well on Windows (via docker-machine) as + well as Linux. Presumably it works on Mac too with docker-machine, but + I've not tested that. + + Because the test suite is docker-machine aware, you can also run it + against a cloud provider, for more realistic network testing, by setting + your cloud provider as your active docker machine. The Appveyor CI setup + in this commit does that because Appveyor doesn't support docker + locally. + +Kamil Dudka (3 Aug 2016) +- [Viktor Szakats brought this change] + + misc.c: Delete unused static variables + + Closes #114 + +Daniel Stenberg (9 Apr 2016) +- [Will Cosgrove brought this change] + + Merge pull request #103 from willco007/patch-2 + + Fix for security issue CVE-2016-0787 + +Alexander Lamaison (2 Apr 2016) +- [Zenju brought this change] + + Fix MSVC 14 compilation errors + + For _MSC_VER == 1900 these macros are not needed and create problems: + + + + 1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\stdio.h(1925): warning C4005: 'snprintf': macro redefinition (compiling source file libssh2-files\src\mac.c) + + 1> \win32\libssh2_config.h(27): note: see previous definition of 'snprintf' (compiling source file libssh2-files\src\mac.c) + + 1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\stdio.h(1927): fatal error C1189: #error: Macro definition of snprintf conflicts with Standard Library function declaration (compiling source file libssh2-files\src\mac.c) + +Daniel Stenberg (26 Mar 2016) +- [Brad Harder brought this change] + + _libssh2_channel_open: speeling error fixed in channel error message + +Alexander Lamaison (15 Mar 2016) +- Link with crypt32.lib on Windows. + + Makes linking with static OpenSSL work again. Although it's not + required for dynamic OpenSSL, it does no harm. + + Fixes #98. + +- [Craig A. Berry brought this change] + + Tweak VMS help file building. + + Primarily this is handling cases where top-level files moved into + the docs/ directory. I also corrected a typo and removed the + claim that libssh2 is public domain. + +- [Craig A. Berry brought this change] + + Build with standard stat structure on VMS. + + This gets us large file support, is available on any VMS release + in the last decade and more, and gives stat other modern features + such as 64-bit ino_t. + +- [Craig A. Berry brought this change] + + Update vms/libssh2_config.h. + + VMS does have stdlib.h, gettimeofday(), and OpenSSL. The latter + is appropriate to hard-wire in the configuration because it's + installed by default as part of the base operating system and + there is currently no libgcrypt port. + +- [Craig A. Berry brought this change] + + VMS can't use %zd for off_t format. + + %z is a C99-ism that VMS doesn't currently have; even though the + compiler is C99-compliant, the library isn't quite. The off_t used + for the st_size element of the stat can be 32-bit or 64-bit, so + detect what we've got and pick a format accordingly. + +- [Craig A. Berry brought this change] + + Normalize line endings in libssh2_sftp_get_channel.3. + + Somehow it got Windows-style CRLF endings so convert to just LF, + for consistency as well as not to confuse tools that will regard + the \r as content (e.g. the OpenVMS help librarian). + +Dan Fandrich (29 Feb 2016) +- libgcrypt: Fixed a NULL pointer dereference on OOM + +Daniel Stenberg (24 Feb 2016) +- [Viktor Szakats brought this change] + + url updates, HTTP => HTTPS + + Closes #87 + +Dan Fandrich (23 Feb 2016) +- RELEASE-NOTES: removed some duplicated names + +Version 1.7.0 (23 Feb 2016) + +Daniel Stenberg (23 Feb 2016) +- web: the site is now HTTPS + +- RELEASE-NOTES: 1.7.0 release + +- diffie_hellman_sha256: convert bytes to bits + + As otherwise we get far too small numbers. + + Reported-by: Andreas Schneider + + CVE-2016-0787 + +Alexander Lamaison (18 Feb 2016) +- Allow CI failures with VS 2008 x64. + + Appveyor doesn't support this combination. + +Daniel Stenberg (16 Feb 2016) +- [Viktor Szakats brought this change] + + GNUmakefile: list system libs after user libs + + Otherwise some referenced WinSock functions will fail to + resolve when linking against LibreSSL 2.3.x static libraries + with mingw. + + Closes #80 + +- [Viktor Szakats brought this change] + + openssl: apply new HAVE_OPAQUE_STRUCTS macro + + Closes #81 + +- [Viktor Szakats brought this change] + + openssl: fix LibreSSL support after OpenSSL 1.1.0-pre1/2 support + +Alexander Lamaison (14 Feb 2016) +- sftp.h: Fix non-C90 type. + + uint64_t does not exist in C90. Use libssh2_uint64_t instead. + +- Exclude sshd tests from AppVeyor. + + They fail complaining that sshd wasn't invoked with an absolute path. + +- Test on more versions of Visual Studio. + +- Fix Appveyor builds. + +Daniel Stenberg (14 Feb 2016) +- [Viktor Szakats brought this change] + + openssl: add OpenSSL 1.1.0-pre3-dev compatibility + + by using API instead of accessing an internal structure. + + Closes #83 + +- RELEASE-NOTES: synced with 996b04ececdf + +- include/libssh2.h: next version is 1.7.0 + +- configure: build "silent" if possible + +- sftp: re-indented some minor stuff + +- [Jakob Egger brought this change] + + sftp.c: ensure minimum read packet size + + For optimum performance we need to ensure we don't request tiny packets. + +- [Jakob Egger brought this change] + + sftp.c: Explicit return values & sanity checks + +- [Jakob Egger brought this change] + + sftp.c: Check Read Packet File Offset + + This commit adds a simple check to see if the offset of the read + request matches the expected file offset. + + We could try to recover, from this condition at some point in the future. + Right now it is better to return an error instead of corrupted data. + +- [Jakob Egger brought this change] + + sftp.c: Don't return EAGAIN if data was written to buffer + +- [Jakob Egger brought this change] + + sftp.c: Send at least one read request before reading + + This commit ensures that we have sent at least one read request before + we try to read data in sftp_read(). + + Otherwise sftp_read() would return 0 bytes (indicating EOF) if the + socket is not ready for writing. + +- [Jakob Egger brought this change] + + sftp.c: stop reading when buffer is full + + Since we can only store data from a single chunk in filep, + we have to stop receiving data as soon as the buffer is full. + + This adresses the following bug report: + https://github.com/libssh2/libssh2/issues/50 + +Salvador Fandiño (21 Jan 2016) +- agent_disconnect_unix: unset the agent fd after closing it + + "agent_disconnect_unix", called by "libssh2_agent_disconnect", was + leaving the file descriptor in the agent structure unchanged. Later, + "libssh2_agent_free" would call again "libssh2_agent_disconnect" under + the hood and it would try to close again the same file descriptor. In + most cases that resulted in just a harmless error, but it is also + possible that the file descriptor had been reused between the two + calls resulting in the closing of an unrelated file descriptor. + + This patch sets agent->fd to LIBSSH2_INVALID_SOCKET avoiding that + issue. + + Signed-off-by: Salvador Fandiño + +Daniel Stenberg (18 Jan 2016) +- [Patrick Monnerat brought this change] + + os400qc3: support encrypted private keys + + PKCS#8 EncryptedPrivateKeyinfo structures are recognized and decoded to get + values accepted by the Qc3 crypto library. + +- [Patrick Monnerat brought this change] + + os400qc3: New PKCS#5 decoder + + The Qc3 library is not able to handle PKCS#8 EncryptedPrivateKeyInfo structures + by itself. It is only capable of decrypting the (encrypted) PrivateKeyInfo + part, providing a key encryption key and an encryption algorithm are given. + Since the encryption key and algorithm description part in a PKCS#8 + EncryptedPrivateKeyInfo is a PKCS#5 structure, such a decoder is needed to + get the derived key method and hash, as well as encryption algorith and + initialisation vector. + +- [Patrick Monnerat brought this change] + + os400qc3: force continuous update on non-final hash/hmac computation + +- [Patrick Monnerat brought this change] + + os400qc3: Be sure hmac keys have a minimum length + + The Qc3 library requires a minimum key length depending on the target + hash algorithm. Append binary zeroes to the given key if not long enough. + This matches RFC 2104 specifications. + +- [Patrick Monnerat brought this change] + + os400qc3: Slave descriptor for key encryption key + + The Qc3 library requires the key encryption key to exist as long as + the encrypted key is used. Its descriptor token is then kept as an + "encrypted key slave" for recursive release. + +- [Patrick Monnerat brought this change] + + os400qc3.c: comment PEM/DER decoding + +- [Patrick Monnerat brought this change] + + os400qc3.c: improve ASN.1 header byte checks + +- [Patrick Monnerat brought this change] + + os400qc3.c: improve OID matching + +- [Patrick Monnerat brought this change] + + os400: os400qc3.c: replace malloc by LIBSSH2_ALLOC or alloca where possible + +- [Patrick Monnerat brought this change] + + os400: asn1_new_from_bytes(): use data from a single element only + +- [Patrick Monnerat brought this change] + + os400: fix an ILE/RPG prototype + +- [Patrick Monnerat brought this change] + + os400: implement character encoding conversion support + +- [Patrick Monnerat brought this change] + + os400: do not miss some external prototypes + + Build procedure extproto() did not strip braces from header files, thus + possibly prepended them to true prototypes. This prevented the prototype to + be recognized as such. + The solution implemented here is to map braces to semicolons, effectively + considering them as potential prototype delimiters. + +- [Patrick Monnerat brought this change] + + os400: Really add specific README + +- [Patrick Monnerat brought this change] + + os400: Add specific README and include new files in dist tarball + +- [Patrick Monnerat brought this change] + + os400: add compilation scripts + +- [Patrick Monnerat brought this change] + + os400: include files for ILE/RPG + + In addition, file os400/macros.h declares all procedures originally + defined as macros. It must not be used for real inclusion and is only + intended to be used as a `database' for macro wrapping procedures generation. + +- [Patrick Monnerat brought this change] + + os400: add supplementary header files/wrappers. Define configuration. + +- [Patrick Monnerat brought this change] + + Protect callback function calls from macro substitution + + Some structure fields holding callback addresses have the same name as the + underlying system function (connect, send, recv). Set parentheses around + their reference to suppress a possible macro substitution. + + Use a macro for connect() on OS/400 to resolve a const/nonconst parameter + problem. + +- [Patrick Monnerat brought this change] + + Add interface for OS/400 crypto library QC3 + +- [Patrick Monnerat brought this change] + + misc: include stdarg.h for debug code + +- [Patrick Monnerat brought this change] + + Document crypto library interface + +- [Patrick Monnerat brought this change] + + Feature an optional crypto-specific macro to rsa sign a data fragment vector + + OS/400 crypto library is unable to sign a precomputed SHA1 hash: however + it does support a procedure that hashes data fragments and rsa signs. + If defined, the new macro _libssh2_rsa_sha1_signv() implements this function + and disables use of _libssh2_rsa_sha1_sign(). + + The function described above requires that the struct iovec unused slacks are + cleared: for this reason, macro libssh2_prepare_iovec() has been introduced. + It should be defined as empty for crypto backends that are not sensitive + to struct iovec unused slack values. + +- [Patrick Monnerat brought this change] + + Fold long lines in include files + +- [Viktor Szakats brought this change] + + kex.c: fix indentation + + Closes #71 + +- [Viktor Szakats brought this change] + + add OpenSSL-1.1.0-pre2 compatibility + + Closes #70 + +- [Viktor Szakats brought this change] + + add OpenSSL 1.1.0-pre1 compatibility + + * close https://github.com/libssh2/libssh2/issues/69 + * sync a declaration with the rest of similar ones + * handle EVP_MD_CTX_new() returning NULL with OpenSSL 1.1.0 + * fix potential memory leak with OpenSSL 1.1.0 in + _libssh2_*_init() functions, when EVP_MD_CTX_new() succeeds, + but EVP_DigestInit() fails. + +Marc Hoersken (22 Dec 2015) +- wincng.c: fixed _libssh2_wincng_hash_final return value + + _libssh2_wincng_hash_final was returning the internal BCRYPT + status code instead of a valid libssh2 return value (0 or -1). + + This also means that _libssh2_wincng_hash never returned 0. + +- wincng.c: fixed possible memory leak in _libssh2_wincng_hash + + If _libssh2_wincng_hash_update failed _libssh2_wincng_hash_final + would never have been called before. + + Reported by Zenju. + +Kamil Dudka (15 Dec 2015) +- [Paul Howarth brought this change] + + libssh2.pc.in: fix the output of pkg-config --libs + + ... such that it does not include LDFLAGS used to build libssh2 itself. + There was a similar fix in the curl project long time ago: + + https://github.com/bagder/curl/commit/curl-7_19_7-56-g4c8adc8 + + Bug: https://bugzilla.redhat.com/1279966 + Signed-off-by: Kamil Dudka + +Marc Hoersken (6 Dec 2015) +- hostkey.c: align code path of ssh_rsa_init to ssh_dss_init + +- hostkey.c: fix invalid memory access if libssh2_dsa_new fails + + Reported by dimmaq, fixes #66 + +Daniel Stenberg (3 Nov 2015) +- [Will Cosgrove brought this change] + + gcrypt: define libssh2_sha256_ctx + + Looks like it didn't make it into the latest commit for whatever reason. + + Closes #58 + +- [Salvador Fandino brought this change] + + libssh2_session_set_last_error: Add function + + Net::SSH2, the Perl wrapping module for libssh2 implements several features* + on top of libssh2 that can fail and so need some mechanism to report the error + condition to the user. + + Until now, besides the error state maintained internally by libssh2, another + error state was maintained at the Perl level for every session object and then + additional logic was used to merge both error states. That is a maintenance + nighmare, and actually there is no way to do it correctly and consistently. + + In order to allow the high level language to add new features to the library + but still rely in its error reporting features the new function + libssh2_session_set_last_error (that just exposses _libssh2_error_flags) is + introduced. + + *) For instance, connecting to a remote SSH service giving the hostname and + port. + + Signed-off-by: Salvador Fandino + Signed-off-by: Salvador Fandiño + +- [Salvador Fandino brought this change] + + _libssh2_error: Support allocating the error message + + Before this patch "_libssh2_error" required the error message to be a + static string. + + This patch adds a new function "_libssh2_error_flags" accepting an + additional "flags" argument and specifically the flag + "LIBSSH2_ERR_FLAG_DUP" indicating that the passed string must be + duplicated into the heap. + + Then, the method "_libssh2_error" has been rewritten to use that new + function under the hood. + + Signed-off-by: Salvador Fandino + Signed-off-by: Salvador Fandiño + +- [Will Cosgrove brought this change] + + added engine.h include to fix warning + +- [sune brought this change] + + kex.c: removed dupe entry from libssh2_kex_methods[] + + Closes #51 + +- [Salvador Fandiño brought this change] + + userauth: Fix off by one error when reading public key file + + After reading the public key from file the size was incorrectly + decremented by one. + + This was usually a harmless error as the last character on the public + key file is an unimportant EOL. But if due to some error the public key + file is empty, the public key size becomes (uint)(0 - 1), resulting in + an unrecoverable out of memory error later. + + Signed-off-by: Salvador Fandi??o + +- [Salvador Fandino brought this change] + + channel: Detect bad usage of libssh2_channel_process_startup + + A common novice programmer error (at least among those using the + wrapping Perl module Net::SSH2), is to try to reuse channels. + + This patchs detects that incorrect usage and fails with a + LIBSSH2_ERROR_BAD_USE error instead of hanging. + + Signed-off-by: Salvador Fandino + +- [Will Cosgrove brought this change] + + kex: Added diffie-hellman-group-exchange-sha256 support + + ... and fixed HMAC_Init depricated usage + + Closes #48 + +Alexander Lamaison (21 Sep 2015) +- Prefixed new #defines to prevent collisions. + + Other libraries might have their own USE_WIN32_*FILES. + +- [keith-daigle brought this change] + + Update examples/scp.c to fix bug where large files on win32 would cause got to wrap and go negative + +- [David Byron brought this change] + + add libssh2_scp_recv2 to support large (> 2GB) files on windows + +Daniel Stenberg (17 Sep 2015) +- [sune brought this change] + + WinCNG: support for SHA256/512 HMAC + + Closes #47 + +- [brian m. carlson brought this change] + + Add support for HMAC-SHA-256 and HMAC-SHA-512. + + Implement support for these algorithms and wire them up to the libgcrypt + and OpenSSL backends. Increase the maximum MAC buffer size to 64 bytes + to prevent buffer overflows. Prefer HMAC-SHA-256 over HMAC-SHA-512, and + that over HMAC-SHA-1, as OpenSSH does. + + Closes #40 + +- [Zenju brought this change] + + kex: free server host key before allocating it (again) + + Fixes a memory leak when Synology server requests key exchange + + Closes #43 + +- [Viktor Szakats brought this change] + + GNUmakefile: up OpenSSL version + + closes #23 + +- [Viktor Szakats brought this change] + + GNUmakefile: add -m64 CFLAGS when targeting mingw64, add -m32/-m64 to LDFLAGS + + libssh2 equivalent of curl patch https://github.com/bagder/curl/commit/d21b66835f2af781a3c2a685abc92ef9f0cd86be + + This allows to build for the non-default target when using a multi-target mingw distro. + Also bump default OpenSSL dependency path to 1.0.2c. + +- [Viktor Szakats brought this change] + + GNUmakefile: add support for LIBSSH2_LDFLAG_EXTRAS + + It is similar to existing LIBSSH2_CFLAG_EXTRAS, but for + extra linker options. + + Also delete some line/file ending whitespace. + + closes #27 + +- [nasacj brought this change] + + hostkey.c: Fix compiling error when OPENSSL_NO_MD5 is defined + + Closes #32 + +- [Mizunashi Mana brought this change] + + openssl.h: adjust the rsa/dsa includes + + ... to work when built without DSA support. + + Closes #36 + +Alexander Lamaison (26 Jul 2015) +- Let CMake build work as a subproject. + + Patch contributed by JasonHaslam. + +- Fix builds with Visual Studio 2015. + + VS2015 moved stdio functions to the header files as inline function. That means check_function_exists can't detect them because it doesn't use header files - just does a link check. Instead we need to use check_symbol_exists with the correct headers. + +Kamil Dudka (2 Jul 2015) +- cmake: include CMake files in the release tarballs + + Despite we announced the CMake support in libssh2-1.6.0 release notes, + the files required by the CMake build system were not included in the + release tarballs. Hence, the only way to use CMake for build was the + upstream git repository. + + This commit makes CMake actually supported in the release tarballs. + +- tests/mansyntax.sh: fix 'make distcheck' with recent autotools + + Do not create symbolic links off the build directory. Recent autotools + verify that out-of-source build works even if the source directory tree + is not writable. + +- openssl: fix memleak in _libssh2_dsa_sha1_verify() + +Daniel Stenberg (12 Jun 2015) +- openssl: make libssh2_sha1 return error code + + - use the internal prefix _libssh2_ for non-exported functions + + - removed libssh2_md5() since it wasn't used + + Reported-by: Kamil Dudka + +- [LarsNordin-LNdata brought this change] + + SFTP: Increase speed and datasize in SFTP read + + The function sftp_read never return more then 2000 bytes (as it should + when I asked Daniel). I increased the MAX_SFTP_READ_SIZE to 30000 but + didn't get the same speed as a sftp read in SecureSSH. I analyzed the + code and found that a return always was dona when a chunk has been read. + I changed it to a sliding buffer and worked on all available chunks. I + got an increase in speed and non of the test I have done has failed + (both local net and over Internet). Please review and test. I think + 30000 is still not the optimal MAX_SFTP_READ_SIZE, my next goal is to + make an API to enable changing this value (The SecureSSH sftp_read has + more complete filled packages when comparing the network traffic) + +- bump: start working on 1.6.1 + +Version 1.6.0 (5 Jun 2015) + +Daniel Stenberg (5 Jun 2015) +- RELEASE-NOTES: synced with 858930cae5c6a + +Marc Hoersken (19 May 2015) +- wincng.c: fixed indentation + +- [sbredahl brought this change] + + wincng.c: fixed memleak in (block) cipher destructor + +Alexander Lamaison (6 May 2015) +- [Jakob Egger brought this change] + + libssh2_channel_open: more detailed error message + + The error message returned by libssh2_channel_open in case of a server side channel open failure is now more detailed and includes the four standard error conditions in RFC 4254. + +- [Hannes Domani brought this change] + + kex: fix libgcrypt memory leaks of bignum + + Fixes #168. + +Marc Hoersken (3 Apr 2015) +- configure.ac: check for SecureZeroMemory for clear memory feature + +- Revert "wincng.c: fix clear memory feature compilation with mingw" + + This reverts commit 2d2744efdd0497b72b3e1ff6e732aa4c0037fc43. + + Autobuilds show that this did not solve the issue. + And it seems like RtlFillMemory is defined to memset, + which would be optimized out by some compilers. + +- wincng.c: fix clear memory feature compilation with mingw + +Alexander Lamaison (1 Apr 2015) +- [LarsNordin-LNdata brought this change] + + Enable use of OpenSSL that doesn't have DSA. + + Added #if LIBSSH2_DSA for all DSA functions. + +- [LarsNordin-LNdata brought this change] + + Use correct no-blowfish #define with OpenSSL. + + The OpenSSL define is OPENSSL_NO_BF, not OPENSSL_NO_BLOWFISH. + +Marc Hoersken (25 Mar 2015) +- configure: error if explicitly enabled clear-memory is not supported + + This takes 22bd8d81d8fab956085e2079bf8c29872455ce59 and + b8289b625e291bbb785ed4add31f4759241067f3 into account, + but still makes it enabled by default if it is supported + and error out in case it is unsupported and was requested. + +Daniel Stenberg (25 Mar 2015) +- configure: make clear-memory default but only WARN if backend unsupported + + ... instead of previous ERROR. + +Marc Hoersken (24 Mar 2015) +- wincng.h: fix warning about computed return value not being used + +- nonblocking examples: fix warning about unused tvdiff on Mac OS X + +Daniel Stenberg (24 Mar 2015) +- openssl: fix compiler warnings + +- cofigure: fix --disable-clear-memory check + +Marc Hoersken (23 Mar 2015) +- scp.c: improved command length calculation + + Reduced number of calls to strlen, because shell_quotearg already + returns the length of the resulting string (e.q. quoted path) + which we can add to the existing and known cmd_len. + Removed obsolete call to memset again, because we can put a final + NULL-byte at the end of the string using the calculated length. + +- scp.c: improved and streamlined formatting + +- scp.c: fix that scp_recv may transmit not initialised memory + +- scp.c: fix that scp_send may transmit not initialised memory + + Fixes ticket 244. Thanks Torsten. + +- kex: do not ignore failure of libssh2_sha1_init() + + Based upon 43b730ce56f010e9d33573fcb020df49798c1ed8. + Fixes ticket 290. Thanks for the suggestion, mstrsn. + +- wincng.h: fix return code of libssh2_md5_init() + +- openssl.c: fix possible segfault in case EVP_DigestInit fails + +- wincng.c: fix possible use of uninitialized variables + +- wincng.c: fix unused argument warning if clear memory is not enabled + +- wincng: Added explicit clear memory feature to WinCNG backend + + This re-introduces the original feature proposed during + the development of the WinCNG crypto backend. It still needs + to be added to libssh2 itself and probably other backends. + + Memory is cleared using the function SecureZeroMemory which is + available on Windows systems, just like the WinCNG backend. + +- wincng.c: fixed mixed line-endings + +- wincng.c: fixed use of invalid parameter types in a8d14c5dcf + +- wincng.c: only try to load keys corresponding to the algorithm + +- wincng.c: moved PEM headers into definitions + +- wincng.h: fixed invalid parameter name + +- wincng: fixed mismatch with declarations in crypto.h + +- userauth.c: fixed warning C6001: using uninitialized sig and sig_len + +- pem.c: fixed warning C6269: possible incorrect order of operations + +- wincng: add support for authentication keys to be passed in memory + + Based upon 18cfec8336e and daa2dfa2db. + +- pem.c: add _libssh2_pem_parse_memory to parse PEM from memory + + Requirement to implement 18cfec8336e for Libgcrypt and WinCNG. + +- pem.c: fix copy and paste mistake from 55d030089b8 + +- userauth.c: fix another possible dereference of a null pointer + +- userauth.c: fix possible dereference of a null pointer + +- pem.c: reduce number of calls to strlen in readline + +Alexander Lamaison (17 Mar 2015) +- [Will Cosgrove brought this change] + + Initialise HMAC_CTX in more places. + + Missed a couple more places we init ctx to avoid openssl threading crash. + +- Build build breakage in WinCNG backend caused when adding libssh2_userauth_publickey_frommemory. + + The new feature isn't implemented for the WinCNG backend currently, but the WinCNG backend didn't contain any implementation of the required backend functions - even ones that returns an error. That caused link errors. + + This change fixes the problem by providing an implementation of the backend functions that returns an error. + +- Fix breakage in WinCNG backend caused by introducing libssh2_hmac_ctx_init. + + The macro was defined to nothing for the libgcrypt backend, but not for WinCNG. This brings the latter into line with the former. + +Daniel Stenberg (15 Mar 2015) +- userauth_publickey_frommemory.3: add AVAILABILITY + + ... it will be added in 1.6.0 + +- libssh2: next version will be called 1.6.0 + + ... since we just added a new function. + +- docs: add libssh2_userauth_publickey_frommemory.3 to dist + + The function and man page were added in commit 18cfec8336e + +- [Jakob Egger brought this change] + + direct_tcpip: Fixed channel write + + There were 3 bugs in this loop: + 1) Started from beginning after partial writes + 2) Aborted when 0 bytes were sent + 3) Ignored LIBSSH2_ERROR_EAGAIN + + See also: + https://trac.libssh2.org/ticket/281 + https://trac.libssh2.org/ticket/293 + +Alexander Lamaison (15 Mar 2015) +- [Will Cosgrove brought this change] + + Must init HMAC_CTX before using it. + + Must init ctx before using it or openssl will reuse the hmac which is not thread safe and causes a crash. + Added libssh2_hmac_ctx_init macro. + +- Add continuous integration configurations. + + Linux-based CI is done by Travis CI. Windows-based CI is done by Appveyor. + +- [David Calavera brought this change] + + Allow authentication keys to be passed in memory. + + All credits go to Joe Turpin, I'm just reaplying and cleaning his patch: + http://www.libssh2.org/mail/libssh2-devel-archive-2012-01/0015.shtml + + * Use an unimplemented error for extracting keys from memory with libgcrypt. + +Daniel Stenberg (14 Mar 2015) +- docs: include the renamed INSTALL* files in dist + +Alexander Lamaison (13 Mar 2015) +- Prevent collisions between CMake and Autotools in examples/ and tests/. + +- Avoid clash between CMake build and Autotools. + + Autotools expects a configuration template file at src/libssh2_config.h.in, which buildconf generates. But the CMake build system has its CMake-specific version of the file at this path. This means that, if you don't run buildconf, the Autotools build will fail because it configured the wrong header template. + + See https://github.com/libssh2/libssh2/pull/8. + +- Merge pull request #8 from alamaison/cmake + + CMake build system. + +- CMake build system. + + Tested: + - Windows: + - Visual C++ 2005/2008/2010/2012/2013/MinGW-w64 + - static/shared + - 32/64-bit + - OpenSSL/WinCNG + - Without zlib + - Linux: + - GCC 4.6.3/Clang 3.4 + - static/shared + - 32/64-bit + - OpenSSL/Libgcrypt + - With/Without zlib + - MacOS X + - AppleClang 6.0.0 + - static + - 64-bit + - OpenSSL + - Without zlib + + Conflicts: + README + +- Man man syntax tests fail gracefully if man version is not suitable. + +- Return valid code from test fixture on failure. + + The sshd test fixture was returning -1 if an error occurred, but negative error codes aren't technically valid (google it). Bash on Windows converted them to 0 which made setup failure look as though all tests were passing. + +- Let mansyntax.sh work regardless of where it is called from. + +Daniel Stenberg (12 Mar 2015) +- [Viktor Szakáts brought this change] + + mingw build: allow to pass custom CFLAGS + + Allow to pass custom `CFLAGS` options via environment variable + `LIBSSH2_CFLAG_EXTRAS`. Default and automatically added options of + `GNUmakefile` have preference over custom ones. This addition is useful + for passing f.e. custom CPU tuning or LTO optimization (`-flto + -ffat-lto-objects`) options. The only current way to do this is to edit + `GNUmakefile`. This patch makes it unnecessary. + + This is a mirror of similar libcurl patch: + https://github.com/bagder/curl/pull/136 + +- [Will Cosgrove brought this change] + + userauth: Fixed prompt text no longer being copied to the prompts struct + + Regression from 031566f9c + +- README: update the git repo locations + +- wait_socket: wrong use of difftime() + + With reversed arguments it would always return a negative value... + + Bug: https://github.com/bagder/libssh2/issues/1 + +- bump: start working toward 1.5.1 now + +Version 1.5.0 (11 Mar 2015) + +Daniel Stenberg (11 Mar 2015) +- RELEASE-NOTES: 1.5.0 release + +- [Mariusz Ziulek brought this change] + + kex: bail out on rubbish in the incoming packet + + CVE-2015-1782 + + Bug: http://www.libssh2.org/adv_20150311.html + +- docs: move INSTALL, AUTHORS, HACKING and TODO to docs/ + + And with this, cleanup README to be shorter and mention the new source + code home. + +- .gitignore: don't ignore INSTALL + +Dan Fandrich (4 Mar 2015) +- examples/x11.c: include sys/select.h for improved portability + +Daniel Stenberg (4 Mar 2015) +- RELEASE-NOTES: synced with a8473c819bc068 + + In preparation for the upcoming 1.5.0 release. + +Guenter Knauf (8 Jan 2015) +- NetWare build: added some missing exports. + +Marc Hoersken (29 Dec 2014) +- knownhost.c: fix use of uninitialized argument variable wrote + + Detected by clang scan in line 1195, column 18. + +- examples/x11.c: fix result of operation is garbage or undefined + + Fix use of uninitialized structure w_size_bck. + Detected by clang scan in line 386, column 28. + +- examples/x11.c: remove dead assigments of some return values + + Detected by clang scan in line 212, column 9. + Detected by clang scan in line 222, column 13. + Detected by clang scan in line 410, column 13. + +- examples/x11.c: fix possible memory leak if read fails + + Detected by clang scan in line 224, column 21. + +- examples/x11.c: fix invalid removal of first list element + + Fix use of memory after it was being freed. + Detected by clang scan in line 56, column 12. + +- userauth.c: make sure that sp_len is positive and avoid overflows + + ... if the pointer subtraction of sp1 - pubkey - 1 resulted in a + negative or larger value than pubkey_len, memchr would fail. + + Reported by Coverity CID 89846. + +- channel.c: remove logically dead code, host cannot be NULL here + + ... host cannot be NULL in line 525, because it is always + valid (e.g. at least set to "0.0.0.0") after lines 430 and 431. + + Reported by Coverity CID 89807. + +- session.c: check return value of session_nonblock during startup + + Reported by Coverity CID 89803. + +- session.c: check return value of session_nonblock in debug mode + + Reported by Coverity CID 89805. + +- pem.c: fix mixed line-endings introduced with 8670f5da24 + +- pem.c: make sure there's a trailing zero and b64data is not NULL + + ... if there is no base64 data between PEM header and footer. + Reported by Coverity CID 89823. + +- kex.c: make sure mlist is not set to NULL + + ... if the currently unsupported LANG methods are called. + Reported by Coverity CID 89834. + +- packet.c: i < 256 was always true and i would overflow to 0 + + Visualize that the 0-termination is intentional, because the array + is later passed to strlen within _libssh2_packet_askv. + +- silence multiple data conversion warnings + +Daniel Stenberg (23 Dec 2014) +- agent_connect_unix: make sure there's a trailing zero + + ... if the path name was too long. Reported by Coverity CID 89801. + +Marc Hoersken (22 Dec 2014) +- examples on Windows: use native SOCKET-type instead of int + + And check return values accordingly. + +- userauth.c: improve readability and clarity of for-loops + +Daniel Stenberg (22 Dec 2014) +- calloc: introduce LIBSSH2_CALLOC() + + A simple function using LIBSSH2_ALLOC + memset, since this pattern was + used in multiple places and this simplies code in general. + +Marc Hoersken (15 Dec 2014) +- libssh2_priv.h: Ignore session, context and format parameters + +- x11 example: check return value of socket function + +- examples: fixed mixed line-endings introduced with aedfba25b8 + +- wincng.c: explicitly ignore BCrypt*AlgorithmProvider return codes + + Fixes VS2012 code analysis warning C6031: + return value ignored: could return unexpected value + +- wincng.c: fix possible invalid memory write access + + Fixes VS2012 code analysis warning C6386: + buffer overrun: accessing 'pbOutput', the writable size is + 'cbOutput' bytes, but '3' bytes may be written: libssh2 wincng.c 610 + +- tests on Windows: check for WSAStartup return code + + Fixes VS2012 code analysis warning C6031: + return value ignored: could return unexpected value + +- wincng.c: fix possible NULL pointer de-reference of bignum + + Fixes VS2012 code analysis warning C6011: + dereferencing NULL pointer 'bignum'. libssh2 wincng.c 1567 + +- wincng.c: fix possible use of uninitialized memory + + Fixes VS2012 code analysis warning C6001: + using uninitialized memory 'cbDecoded'. libssh2 wincng.c 553 + +- packet.c: fix possible NULL pointer de-reference within listen_state + + Fixes VS2012 code analysis warning C6011: + dereferencing NULL pointer 'listen_state->channel'. libssh2 packet.c 221 + +- kex.c: fix possible NULL pointer de-reference with session->kex + + Fixes VS2012 code analysis warning C6011: + dereferencing NULL pointer 'session->kex'. libssh2 kex.c 1761 + +- agent.c: check return code of MapViewOfFile + + Fixes VS2012 code analysis warning C6387: 'p+4' may be '0': + this does not adhere to the specification for the function + 'memcpy': libssh2 agent.c 330 + + Fixes VS2012 code analysis warning C6387: 'p' may be '0': + this does not adhere to the specification for the function + 'UnmapViewOfFile': libssh2 agent.c 333 + +- examples on Windows: check for socket return code + + Fixes VS2012 code analysis warning C28193: + The variable holds a value that must be examined + +- examples on Windows: check for WSAStartup return code + + Fixes VS2012 code analysis warning C6031: + return value ignored: could return unexpected value + +Guenter Knauf (11 Dec 2014) +- wincng.c: silent some more gcc compiler warnings. + +- wincng.c: silent gcc compiler warnings. + +- Watcom build: added support for WinCNG build. + +- build: updated dependencies in makefiles. + +Daniel Stenberg (4 Dec 2014) +- configure: change LIBS not LDFLAGS when checking for libs + + Closes #289 + + Patch-by: maurerpe + +Guenter Knauf (3 Dec 2014) +- MinGW build: some more GNUMakefile tweaks. + + test/GNUmakefile: added architecture autodetection; added switches to + CFLAGS and RCFLAGS to make sure that the right architecture is used. + Added support to build with WinCNG. + +- sftpdir.c: added authentication method detection. + + Stuff copied over from ssh2.c to make testing a bit easier. + +- NMake build: fixed LIBS settings. + +- NMake build: added support for WinCNG build. + +- MinGW build: some GNUMakefile tweaks. + + Added architecture autodetection; added switches to CFLAGS and + RCFLAGS to make sure that the right architecture is used. + Added support to build with WinCNG. + +- MinGW build: Fixed redefine warnings. + +- Updated copyright year. + +Daniel Stenberg (31 Aug 2014) +- COPYING: bump the copyright year + +Dan Fandrich (28 Jul 2014) +- docs: fixed a bunch of typos + +- docs: added missing libssh2_session_handshake.3 file + +Marc Hoersken (19 May 2014) +- wincng.c: specify the required libraries for dependencies using MSVC + + Initially reported by Bob Kast as "for MS VS builds, specify the + libraries that are required so they don't need to go into all + project files that may use this library". Thanks a lot. + +- [Bob Kast brought this change] + + windows build: do not export externals from static library + + If you are building a DLL, then you need to explicitly export each + entry point. When building a static library, you should not. + + libssh2 was exporting the entry points whether it was building a DLL or a + static library. To elaborate further, if libssh2 was used as a static + library, which was being linked into a DLL, the libssh2 API would be + exported from that separate DLL. + +Daniel Stenberg (19 May 2014) +- [Mikhail Gusarov brought this change] + + Fix typos in manpages + +Marc Hoersken (18 May 2014) +- wincng.c: Fixed memory leak in case of an error during ASN.1 decoding + +- configure: Display individual crypto backends on separate lines + + This avoids line-wrapping in between parameters and makes the + error message look like the following: + + configure: error: No crypto library found! + Try --with-libssl-prefix=PATH + or --with-libgcrypt-prefix=PATH + or --with-wincng on Windows + +- [Bob Kast brought this change] + + libssh2_priv.h: a 1 bit bit-field should be unsigned + + some compilers may not like this + +- knownhost.c: Fixed warning that pointer targets differ in signedness + +- wincng.c: Fixed warning about pointer targets differing in signedness + +- tcpip-forward.c: Fixed warning that pointer targets differ in signedness + + libssh2_channel_forward_listen_ex uses ints instead of unsigned ints. + +- misc.c: Fixed warning about mixed declarations and code + +- libgcrypt.h: Fixed warning about pointer targets differing in signedness + +- wincng.h: Fixed warning about pointer targets differing in signedness + +- misc.c: Fixed warning about unused parameter abstract + +- tcpip-forward.c: Removed unused variables shost, sport and sockopt + +- wincng.h: Added forward declarations for all WinCNG functions + + Initially reported by Bob Kast as "Wincng - define function + prototypes for wincng routines". Thanks a lot. + + Also replaced structure definitions with type definitions. + +- [Bob Kast brought this change] + + libssh2.h: on Windows, a socket is of type SOCKET, not int + +- win32: Added WinCNG targets to generated Visual Studio project + + Inspired by Bob Kast's reports, this commit enables the compilation + of libssh2 with WinCNG using the generated Visual Studio project files. + This commit adds WinCNG support to parts of the existing Win32 build + infrastructure, until new build systems, like pre-defined VS project + files or CMake files may be added. + + This commit and b20bfeb3e519119a48509a1099c06d65aa7da1d7 raise one + question: How to handle build systems, like VS project files, that + need to include all source files regardless of the desired target, + including all supported crypto backends? For now the mentioned commit + added a check for LIBSSH2_OPENSSL to openssl.c and with this commit + the supported crypto backends are hardcoded within Makefile.am. + +- libssh2_priv msvc: Removed redundant definition of inline keyword + + Initially reported by Bob Kast as "Remove redundant 'inline' define". + Thanks a lot. + +- wincng: Made data parameter to hash update function constant + + Initially reported by Bob Kast as "formal parameter must be const + since it is used in contexts where the actual parameter may be const". + Thanks a lot. + +- wincng: fix cross-compilation against the w64 mingw-runtime package + +- openssl: Check for LIBSSH2_OPENSSL in order to compile with openssl + +- wincng: Fixed use of possible uninitialized variable pPaddingInfo + + Reported by Bob Kast, thanks a lot. + +- wincng: Added cast for double to unsigned long conversion + +- wincng: Cleaned up includes and check NTSTATUS using macro + + Removed header file combination that is not supported on a real + Windows platform and can only be compiled using MinGW. Replaced + custom NTSTATUS return code checks with BCRYPT_SUCCESS macro. + +Daniel Stenberg (16 Mar 2014) +- userauth_hostbased_fromfile: zero assign to avoid uninitialized use + + Detected by clang-analyze + +- channel_receive_window_adjust: store windows size always + + Avoid it sometimes returning without storing it, leaving calling + functions with unknown content! + + Detected by clang-analyzer + +- publickey_packet_receive: avoid junk in returned pointers + + clang-analyzer found this risk it would return a non-initialized pointer + in a success case + +Peter Stuge (16 Mar 2014) +- [Marc Hoersken brought this change] + + Added Windows Cryptography API: Next Generation based backend + +- [Marc Hoersken brought this change] + + knownhost.c: fixed that 'key_type_len' may be used uninitialized + + ../src/knownhost.c: In function 'libssh2_knownhost_readline': + ../src/knownhost.c:651:16: warning: 'key_type_len' may be used + uninitialized in this function [-Wmaybe-uninitialized] + rc = knownhost_add(hosts, hostbuf, NULL, + ^ + ../src/knownhost.c:745:12: note: 'key_type_len' was declared here + size_t key_type_len; + ^ + +- [Marc Hoersken brought this change] + + pem.c: always compile pem.c independently of crypto backend + +- Fix non-autotools builds: Always define the LIBSSH2_OPENSSL CPP macro + + Commit d512b25f69a1b6778881f6b4b5ff9cfc6023be42 introduced a crypto + library abstraction in the autotools build system, to allow us to more + easily support new crypto libraries. In that process it was found that + all other build system which we support are hard-coded to build with + OpenSSL. Commit f5c1a0d98bd51aeb24aca3d49c7c81dcf8bd858d fixes automake + introduced into non-autotools build systems but still overlooked the + CPP macro saying that we are using OpenSSL. + + Thanks to Marc Hörsken for identifying this issue and proposing a fix + for win32/{GNUmakefile,config.mk}. This commit uses a slightly different + approach but the end result is the same. + +Dan Fandrich (15 Mar 2014) +- channel_close: Close the channel even in the case of errors + +- sftp_close_handle: ensure the handle is always closed + + Errors are reported on return, but otherwise the close path is + completed as much as possible and the handle is freed on exit. + +Alexander Lamaison (6 Mar 2014) +- knownhost: Restore behaviour of `libssh2_knownhost_writeline` with short buffer. + + Commit 85c6627c changed the behaviour of `libssh2_knownhost_writeline` so that it stopped returning the number of bytes needed when the given buffer was too small. Also, the function changed such that is might write to part of the buffer before realising it is too small. + + This commit restores the original behaviour, whilst keeping the unknown-key-type functionality that 85c6627c. Instead of writing to the buffer piecemeal, the length of the various parts is calculated up front and the buffer written only if there is enough space. The calculated necessary size is output in `outlen` regardless of whether the buffer was written to. + + The main use-case for the original behaviour that this commit restores is to allow passing in a NULL buffer to get the actual buffer size needed, before calling the function again with the buffer allocated to the exact size required. + +- knownhost: Fix DSS keys being detected as unknown. + + I missing `else` meant ssh-dss format keys were being re-detected as unknown format. + +Dan Fandrich (6 Mar 2014) +- knownhosts: Abort if the hosts buffer is too small + + This could otherwise cause a match on the wrong host + +- agent_list_identities: Fixed memory leak on OOM + +- Fixed a few typos + +- userauth: Fixed an attempt to free from stack on error + +- Fixed a few memory leaks in error paths + +- Fixed two potential use-after-frees of the payload buffer + + The first might occur if _libssh2_packet_add returns an error, as + fullpacket_state wasn't reset to idle so if it were possible for + fullpacket to be called again, it would return to the same state + handler and re-use the freed p->packet buffer. + + The second could occur if decrypt returned an error, as it freed the + packet buffer but did not clear total_num, meaning that freed buffer + could be written into again later. + +Alexander Lamaison (28 Nov 2013) +- Fix missing `_libssh2_error` in `_libssh2_channel_write`. + + In one case, the error code from `_libssh2_transport_read` was being returned from `_libssh2_channel_write` without setting it as the last error by calling `_libssh2_error`. This commit fixes that. + + Found when using a session whose socket had been inadvertently destroyed. The calling code got confused because via `libssh2_session_last_error` it appeared no error had occurred, despite one being returned from the previous function. + +Kamil Dudka (21 Nov 2013) +- [Mark McPherson brought this change] + + openssl: initialise the digest context before calling EVP_DigestInit() + + When using the OpenSSL libraries in FIPS mode, the function call + EVP_DigestInit() is actually #defined to FIPS_digestinit(). + Unfortunately wheres EVP_DigestInit() initialises the context and then + calls EVP_DigestInit_ex(), this function assumes that the context has + been pre-initialised and crashes when it isn't. + + Bug: https://trac.libssh2.org/ticket/279 + + Fixes #279 + +- [Marc Hörsken brought this change] + + .gitignore: Ignore files like src/libssh2_config.h.in~ + +Peter Stuge (13 Nov 2013) +- Move automake conditionals added by commit d512b25f out of Makefile.inc + + Commit d512b25f69a1b6778881f6b4b5ff9cfc6023be42 added automake + conditionals to Makefile.inc but since Makefile.inc is included + from Makefile for all other build systems that does not work. + + This commit instead adds Makefile.OpenSSL.inc and Makefile.libgcrypt.inc + and moves the automake conditional to its proper place, src/Makefile.am. + + The automake conditional includes the correct Makefile.$name.inc per + the crypto library selection/detection done by configure. + + All non-autotools build system files in libssh2 are hardcoded to use + OpenSSL and do not get a conditional but at least there is some reuse + because they can all include the new Makefile.OpenSSL.inc. + +Daniel Stenberg (27 Oct 2013) +- [Salvador Fandino brought this change] + + Set default window size to 2MB + + The default channel window size used until now was 256KB. This value is + too small and results on a bottleneck on real-life networks where + round-trip delays can easily reach 300ms. + + The issue was not visible because the configured channel window size + was being ignored and a hard-coded value of ~22MB being used instead, + but that was fixed on a previous commit. + + This patch just changes the default window size + (LIBSSH2_CHANNEL_WINDOW_DEFAULT) to 2MB. It is the same value used by + OpenSSH and in our opinion represents a good compromise between memory + used and transfer speed. + + Performance tests were run to determine the optimum value. The details + and related discussion are available from the following thread on the + libssh2 mailing-list: + + http://www.libssh2.org/mail/libssh2-devel-archive-2013-10/0018.shtml + http://article.gmane.org/gmane.network.ssh.libssh2.devel/6543 + + An excerpt follows: + + "I have been running some transfer test and measuring their speed. + + My setup was composed of a quad-core Linux machine running Ubuntu 13.10 + x86_64 with a LXC container inside. The data transfers were performed + from the container to the host (never crossing through a physical + network device). + + Network delays were simulated using the tc tool. And ping was used to + verify that they worked as intended during the tests. + + The operation performed was the equivalent to the following ssh command: + + $ ssh container "dd bs=16K count=8K if=/dev/zero" >/dev/null + + Though, establishment and closing of the SSH connection was excluded + from the timings. + + I run the tests several times transferring files of sizes up to 128MB + and the results were consistent between runs. + + The results corresponding to the 128MB transfer are available here: + + https://docs.google.com/spreadsheet/ccc?key=0Ao1yRmX6PQQzdG5wSFlrZl9HRWNET3ZyN0hnaGo5ZFE&usp=sharing + + It clearly shows that 256KB is too small as the default window size. + Moving to a 512MB generates a great improvement and after the 1MB mark + the returns rapidly diminish. Other factors (TCP window size, probably) + become more limiting than the channel window size + + For comparison I also performed the same transfers using OpenSSH. Its + speed is usually on par with that of libssh2 using a window size of 1MB + (even if it uses a 2MB window, maybe it is less aggressive sending the + window adjust msgs)." + + Signed-off-by: Salvador Fandino + +- [Salvador brought this change] + + _libssh2_channel_read: Honour window_size_initial + + _libssh2_channel_read was using an arbitrary hard-coded limit to trigger + the window adjusting code. The adjustment used was also hard-coded and + arbitrary, 15MB actually, which would limit the usability of libssh2 on + systems with little RAM. + + This patch, uses the window_size parameter passed to + libssh2_channel_open_ex (stored as remote.window_size_initial) plus the + buflen as the base for the trigger and the adjustment calculation. + + The memory usage when using the default window size is reduced from 22MB + to 256KB per channel (actually, if compression is used, these numbers + should be incremented by ~50% to account for the errors between the + decompressed packet sizes and the predicted sizes). + + My tests indicate that this change does not impact the performance of + transfers across localhost or a LAN, being it on par with that of + OpenSSH. On the other hand, it will probably slow down transfers on + networks with high bandwidth*delay when the default window size + (LIBSSH2_CHANNEL_WINDOW_DEFAULT=256KB) is used. + + Signed-off-by: Salvador Fandino + +- [Salvador Fandino brought this change] + + knownhosts: handle unknown key types + + Store but don't use keys of unsupported types on the known_hosts file. + + Currently, when libssh2 parses a known_host file containing keys of some + type it doesn't natively support, it stops reading the file and returns + an error. + + That means, that the known_host file can not be safely shared with other + software supporting other key types (i.e. OpenSSH). + + This patch adds support for handling keys of unknown type. It can read + and write them, even if they are never going to be matched. + + At the source level the patch does the following things: + + - add a new unknown key type LIBSSH2_KNOWNHOST_KEY_UNKNOWN + + - add a new slot (key_type_name) on the known_host struct that is + used to store the key type in ascii form when it is not supported + + - parse correctly known_hosts entries with unknown key types and + populate the key_type_name slot + + - print correctly known_hosts entries of unknown type + + - when checking a host key ignore keys that do not match the key + + Fixes #276 + +- windows build: fix build errors + + Fixes various link errors with VS2010 + + Reported-by: "kdekker" + Fixes #272 + +- man page: add missing function argument + + for libssh2_userauth_publickey_fromfile_ex() + + Reported-by: "pastey" + + Fixes #262 + +- [Salvador brought this change] + + Fix zlib deflate usage + + Deflate may return Z_OK even when not all data has been compressed + if the output buffer becomes full. + + In practice this is very unlikely to happen because the output buffer + size is always some KBs larger than the size of the data passed for + compression from the upper layers and I think that zlib never expands + the data so much, even on the worst cases. + + Anyway, this patch plays on the safe side checking that the output + buffer is not exhausted. + + Signed-off-by: Salvador + +- [Salvador brought this change] + + comp_method_zlib_decomp: Improve buffer growing algorithm + + The old algorithm was O(N^2), causing lots and lots of reallocations + when highly compressed data was transferred. + + This patch implements a simpler one that just doubles the buffer size + everytime it is exhausted. It results in O(N) complexity. + + Also a smaller inflate ratio is used to calculate the initial size (x4). + + Signed-off-by: Salvador + +- [Salvador brought this change] + + Fix zlib usage + + Data may remain in zlib internal buffers when inflate() returns Z_OK + and avail_out == 0. In that case, inflate has to be called again. + + Also, once all the data has been inflated, it returns Z_BUF_ERROR to + signal that the input buffer has been exhausted. + + Until now, the way to detect that a packet payload had been completely + decompressed was to check that no data remained on the input buffer + but that didn't account for the case where data remained on the internal + zlib buffers. + + That resulted in packets not being completely decompressed and the + missing data reappearing on the next packet, though the bug was masked + by the buffer allocation algorithm most of the time and only manifested + when transferring highly compressible data. + + This patch fixes the zlib usage. + + Signed-off-by: Salvador + +- [Salvador brought this change] + + _libssh2_channel_read: fix data drop when out of window + + After filling the read buffer with data from the read queue, when the + window size was too small, "libssh2_channel_receive_window_adjust" was + called to increase it. In non-blocking mode that function could return + EAGAIN and, in that case, the EAGAIN was propagated upwards and the data + already read on the buffer lost. + + The function was also moving between the two read states + "libssh2_NB_state_idle" and "libssh2_NB_state_created" both of which + behave in the same way (excepting a debug statment). + + This commit modifies "_libssh2_channel_read" so that the + "libssh2_channel_receive_window_adjust" call is performed first (when + required) and if everything goes well, then it reads the data from the + queued packets into the read buffer. + + It also removes the useless "libssh2_NB_state_created" read state. + + Some rotted comments have also been updated. + + Signed-off-by: Salvador + +- [Salvador Fandino brought this change] + + window_size: redid window handling for flow control reasons + + Until now, the window size (channel->remote.window_size) was being + updated just after receiving the packet from the transport layer. + + That behaviour is wrong because the channel queue may grow uncontrolled + when data arrives from the network faster that the upper layer consumes + it. + + This patch adds a new counter, read_avail, which keeps a count of the + bytes available from the packet queue for reading. Also, now the window + size is adjusted when the data is actually read by an upper layer. + + That way, if the upper layer stops reading data, the window will + eventually fill and the remote host will stop sending data. When the + upper layers reads enough data, a window adjust packet is delivered and + the transfer resumes. + + The read_avail counter is used to detect the situation when the remote + server tries to send data surpassing the window size. In that case, the + extra data is discarded. + + Signed-off-by: Salvador + +Peter Stuge (15 Sep 2013) +- configure.ac: Call zlib zlib and not libz in text but keep option names + +- configure.ac: Reorder --with-* options in --help output + +- configure.ac: Rework crypto library detection + + This further simplifies adding new crypto libraries. + +- Clean up crypto library abstraction in build system and source code + + libssh2 used to explicitly check for libgcrypt and default to OpenSSL. + + Now all possible crypto libraries are checked for explicitly, making + the addition of further crypto libraries both simpler and cleaner. + +- configure.ac: Add zlib to Requires.private in libssh2.pc if using zlib + +- Revert "Added Windows Cryptography API: Next Generation based backend" + + This reverts commit d385230e15715e67796f16f3e65fd899f21a638b. + +Daniel Stenberg (7 Sep 2013) +- [Leif Salomonsson brought this change] + + sftp_statvfs: fix for servers not supporting statfvs extension + + Fixes issue arising when server does not support statfvs and or fstatvfs + extensions. sftp_statvfs() and sftp_fstatvfs() after this patch will + handle the case when SSH_FXP_STATUS is returned from server. + +- [Marc Hoersken brought this change] + + Added Windows Cryptography API: Next Generation based backend + +- [Kamil Dudka brought this change] + + partially revert "window_size: explicit adjustments only" + + This partially reverts commit 03ca9020756a4e16f0294e5b35e9826ee6af2364 + in order to fix extreme slowdown when uploading to localhost via SFTP. + + I was able to repeat the issue on RHEL-7 on localhost only. It did not + occur when uploading via network and it did not occur on a RHEL-6 box + with the same version of libssh2. + + The problem was that sftp_read() used a read-ahead logic to figure out + the window_size, but sftp_packet_read() called indirectly from + sftp_write() did not use any read-ahead logic. + +- _libssh2_channel_write: client spins on write when window full + + When there's no window to "write to", there's no point in waiting for + the socket to become writable since it most likely just will continue to + be. + + Patch-by: ncm + Fixes #258 + +- _libssh2_channel_forward_cancel: avoid memory leaks on error + + Fixes #257 + +- _libssh2_packet_add: avoid using uninitialized memory + + In _libssh2_packet_add, called by _libssh2_packet_read, a call to + _libssh2_packet_send that is supposed to send a one-byte message + SSH_MSG_REQUEST_FAILURE would send an uninitialized byte upon re-entry + if its call to _send returns _EAGAIN. + + Fixes #259 + +- _libssh2_channel_forward_cancel: accessed struct after free + + ... and the assignment was pointless anyway since the struct was about + to be freed. Bug introduced in dde2b094. + + Fixes #268 + +Peter Stuge (2 Jun 2013) +- [Marc Hoersken brought this change] + + Fixed compilation using mingw-w64 + +- [Marc Hoersken brought this change] + + knownhost.c: use LIBSSH2_FREE macro instead of free + + Use LIBSSH2_FREE instead of free since + _libssh2_base64_encode uses LIBSSH2_ALLOC + +Daniel Stenberg (18 May 2013) +- [Matthias Kerestesch brought this change] + + libssh2_agent_init: init ->fd to LIBSSH2_INVALID_SOCKET + + ... previously it was left at 0 which is a valid file descriptor! + + Bug: https://trac.libssh2.org/ticket/265 + + Fixes #265 + +- userauth_password: pass on the underlying error code + + _libssh2_packet_requirev() may return different errors and we pass that + to the parent instead of rewriting it. + + Bug: http://libssh2.org/mail/libssh2-devel-archive-2013-04/0029.shtml + Reported by: Cosmin + +Peter Stuge (9 May 2013) +- [Marc Hoersken brought this change] + + libcrypt.c: Fix typo in _libssh2_rsa_sha1_sign() parameter type + +Kamil Dudka (4 May 2013) +- configure.ac: replace AM_CONFIG_HEADER with AC_CONFIG_HEADERS + + Reported by: Quintus + Bug: https://trac.libssh2.org/ticket/261 + +Guenter Knauf (12 Apr 2013) +- Fixed copyright string for NetWare build. + +Daniel Stenberg (9 Apr 2013) +- [Richard W.M. Jones brought this change] + + sftp: Add support for fsync (OpenSSH extension). + + The new libssh2_sftp_fsync API causes data and metadata in the + currently open file to be committed to disk at the server. + + This is an OpenSSH extension to the SFTP protocol. See: + + https://bugzilla.mindrot.org/show_bug.cgi?id=1798 + +- [Richard W.M. Jones brought this change] + + sftp: statvfs: Along error path, reset the correct 'state' variable. + +- [Richard W.M. Jones brought this change] + + sftp: seek: Don't flush buffers on same offset + + Signed-off-by: Richard W.M. Jones + +Guenter Knauf (9 Feb 2013) +- Updated dependency libs. + +- Fixed tool macro names. + +Daniel Stenberg (29 Nov 2012) +- [Seth Willits brought this change] + + compiler warnings: typecast strlen in macros + + ... in macro parameters to avoid compiler warnings about lost precision. + + Several macros in libssh2.h call strlen and pass the result directly to + unsigned int parameters of other functions, which warns about precision + loss because strlen returns size_t which is unsigned long on at least + some platforms (such as OS X). The fix is to simply typecast the + strlen() result to unsigned int. + +- libssh2.h: bump version to 1.4.4-DEV + +Version 1.4.3 (27 Nov 2012) + +Daniel Stenberg (27 Nov 2012) +- RELEASE-NOTES: fixed for 1.4.3 + +- sftp_read: return error if a too large package arrives + +Peter Stuge (13 Nov 2012) +- Only define _libssh2_dsa_*() functions when building with DSA support + +Guenter Knauf (8 Nov 2012) +- Added .def file to output. + +Kamil Dudka (1 Nov 2012) +- libssh2_hostkey_hash.3: update the description of return value + + The function returns NULL also if the hash algorithm is not available. + +Guenter Knauf (24 Oct 2012) +- Fixed mode acciedently committed. + +- Ignore generated file. + +- Added hack to make use of Makefile.inc. + + This should avoid further maintainance of the objects list. + +- Fixed MSVC NMakefile. + + Added missing source files; added resource for DLL. + +Kamil Dudka (22 Oct 2012) +- examples: use stderr for messages, stdout for data + + Reported by: Karel Srot + Bug: https://bugzilla.redhat.com/867462 + +- openssl: do not leak memory when handling errors + + ,.. in aes_ctr_init(). Detected by Coverity. + +- channel: fix possible NULL dereference + + ... in libssh2_channel_get_exit_signal(). Detected by Coverity. + +- Revert "aes: the init function fails when OpenSSL has AES support" + + This partially reverts commit f4f2298ef3635acd031cc2ee0e71026cdcda5864. + + We need to use the EVP_aes_???_ctr() functions in FIPS mode. + +- crypt: use hard-wired cipher block sizes consistently + +- openssl: do not ignore failure of EVP_CipherInit() + +- kex: do not ignore failure of libssh2_md5_init() + + The MD5 algorithm is disabled when running in FIPS mode. + +Daniel Stenberg (21 Aug 2012) +- [Peter Krempa brought this change] + + known_hosts: Fail when parsing unknown keys in known_hosts file. + + libssh2_knownhost_readfile() silently ignored problems when reading keys + in unsupported formats from the known hosts file. When the file is + written again from the internal structures of libssh2 it gets truntcated + to the point where the first unknown key was located. + + * src/knownhost.c:libssh2_knownhost_readfile() - return error if key + parsing fails + +- AUTHORS: synced with 42fec44c8a4 + + 31 recent authors added + +- [Dave Hayden brought this change] + + compression: add support for zlib@openssh.com + + Add a "use_in_auth" flag to the LIBSSH2_COMP_METHOD struct and a + separate "zlib@openssh.com" method, along with checking session->state + for LIBSSH2_STATE_AUTHENTICATED. Appears to work on the OpenSSH servers + I've tried against, and it should work as before with normal zlib + compression. + +- [Dmitry Smirnov brought this change] + + configure: gcrypt doesn't come with pkg-config support + + ... so use plain old -lgcrypt to the linker to link with it. + + Fixes #225 + +- sftp_read: Value stored to 'next' is never read + + Detected by clang-analyzer + +- publickey_init: errors are negative, fix check + + Detected by clang-analyzer. + +- [Maxime Larocque brought this change] + + session_free: wrong variable used for keeping state + + If libssh2_session_free is called without the channel being freed + previously by libssh2_channel_free a memory leak could occur. + + A mismatch of states variables in session_free() prevent the call to + libssh2_channel_free function. session->state member is used instead of + session->free_state. + + It causes a leak of around 600 bytes on every connection on my systems + (Linux, x64 and PPC). + + (Debugging done under contract for Accedian Networks) + + Fixes #246 + +Guenter Knauf (29 Jun 2012) +- Small NetWare makefile tweak. + +- Some small Win32 makefile fixes. + +Daniel Stenberg (19 Jun 2012) +- libssh2_userauth_publickey_fromfile_ex.3: mention publickey == NULL + +- comp_method_zlib_decomp: handle Z_BUF_ERROR when inflating + + When using libssh2 to perform an SFTP file transfer from the "JSCAPE MFT + Server" (http://www.jscape.com) the transfer failed. The default JSCAPE + configuration is to enforce zlib compression on SSH2 sessions so the + session was compressed. The relevant part of the debug trace contained: + + [libssh2] 1.052750 Transport: unhandled zlib error -5 + [libssh2] 1.052750 Failure Event: -29 - decompression failure + + The trace comes from comp_method_zlib_decomp() in comp.c. The "unhandled + zlib error -5" is the status returned from the zlib function + inflate(). The -5 status corresponds to "Z_BUF_ERROR". + + The inflate() function takes a pointer to a z_stream structure and + "inflates" (decompresses) as much as it can. The relevant fields of the + z_stream structure are: + + next_in - pointer to the input buffer containing compressed data + avail_in - the number of bytes available at next_in + next_out - pointer to the output buffer to be filled with uncompressed + data + avail_out - how much space available at next_out + + To decompress data you set up a z_stream struct with the relevant fields + filled in and pass it to inflate(). On return the fields will have been + updated so next_in and avail_in show how much compressed data is yet to + be processed and next_out and avail_out show how much space is left in + the output buffer. + + If the supplied output buffer is too small then on return there will be + compressed data yet to be processed (avail_in != 0) and inflate() will + return Z_OK. In this case the output buffer must be grown, avail_out + updated and inflate() called again. + + If the supplied output buffer was big enough then on return the + compressed data will have been exhausted (avail_in == 0) and inflate() + will return Z_OK, so the data has all been uncompressed. + + There is a corner case where inflate() makes no progress. That is, there + may be unprocessed compressed data and space available in the output + buffer and yet the function does nothing. In this case inflate() will + return Z_BUF_ERROR. From the zlib documentation and the source code it + is not clear under what circumstances this happens. It could be that it + needs to write multiple bytes (all in one go) from its internal state to + the output buffer before processing the next chunk of input but but + can't because there is not enough space (though my guesses as to the + cause are not really relevant). Recovery from Z_BUF_ERROR is pretty + simple - just grow the output buffer, update avail_out and call + inflate() again. + + The comp_method_zlib_decomp() function does not handle the case when + inflate() returns Z_BUF_ERROR. It treats it as a non-recoverable error + and basically aborts the session. + + Fixes #240 + +Guenter Knauf (12 Jun 2012) +- MinGW makefile tweaks. + + Use GNU tools when compiling on Linux. + Fixed dist and dev targets. + +- NetWare makefile tweaks. + + Changed to use Windows commandline tools instead of + GNU tools when compiling on Windows. Fixed dist and + dev targets. Enabled nlmconv error for unresolved + symbols. + +Daniel Stenberg (11 Jun 2012) +- Revert "config.rpath: generated file, no need to keep in git" + + This reverts commit 1ac7bd09cc685755577fb2c8829adcd081e7ab3c. + + This file still used by lib/*m4 functions so we need to keep the file + around. + +- BINDINGS: added PySsh2, a Python-ctypes binding + +Guenter Knauf (8 Jun 2012) +- Fixed MinGW debug build. + +Daniel Stenberg (5 Jun 2012) +- BINDINGS: Added the Cocoa/Objective-C one + + ... and sorted the bindings after the languages, alphabetically + + Reported by: Mike Abdullah + +- BINDINGS: document the bindings we know of + +Guenter Knauf (4 Jun 2012) +- Fixed LIBSSH2_INT64_T_FORMAT macro. + + Usually a format macro should hold the whole format, otherwise + it should be named a prefix. Also fixed usage of this macro in + scp.c for a signed var where it was used as prefix for unsigned. + +- Removed obsolete define from makefiles. + +- Renamed NetWare makefiles. + +- Renamed NetWare makefiles. + +- Synced MinGW makefiles with 56c64a6..39e438f. + + Also synced MinGW test makefile with b092696..f8cb874. + +Peter Stuge (30 May 2012) +- Revert "sftp: Don't send attrs.permissions on read-only SSH_FXP_OPEN" + + This reverts commit 04e79e0c798674a0796be8a55f63dd92e6877790. + +- sftp: Don't send attrs.permissions on read-only SSH_FXP_OPEN + + This works around a protocol violation in the ProFTPD 1.3.4 mod_sftp + server, as reported by Will Cosgrove in: + + http://libssh2.org/mail/libssh2-devel-archive-2012-05/0079.shtml + + Based on a suggested fix by TJ Saunders in: + + http://libssh2.org/mail/libssh2-devel-archive-2012-05/0104.shtml + +Guenter Knauf (28 May 2012) +- Try to detect OpenSSL build type automatically. + + Also fixed recently added libgdi32 linkage which is only + required when OpenSSL libs are linked statically. + +Daniel Stenberg (25 May 2012) +- config.rpath: generated file, no need to keep in git + +Guenter Knauf (22 May 2012) +- Updated dependency libary versions. + +Daniel Stenberg (18 May 2012) +- 1.4.3: towards the future + +Version 1.4.2 (18 May 2012) + +Daniel Stenberg (18 May 2012) +- RELEASE-NOTES: synced with 92a9f952794 + +Alexander Lamaison (15 May 2012) +- win32/libssh2_config.h: Remove hardcoded #define LIBSSH2_HAVE_ZLIB. + + Rationale: Everything else in this file states a fact about the win32 + platform that is unconditional for that platform. There is nothing + unconditional about the presence of zlib. It is neither included with + Windows nor with the platform SDK. Therefore, this is not an appropriate + place to assert its presence. Especially as, once asserted, it cannot be + overridden using a compiler flag. + + In contrast, if it is omitted, then it can easily be reasserted by adding + a compiler flag defining LIBSSH2_HAVE_ZLIB. + +Daniel Stenberg (14 May 2012) +- RELEASE-NOTES: synced with 69a3354467c + +- _libssh2_packet_add: SSH_MSG_CHANNEL_REQUEST default to want_reply + + RFC4254 says the default 'want_reply' is TRUE but the code defaulted to + FALSE. Now changed. + + Fixes #233 + +- gettimeofday: no need for a replacement under cygwin + + Fixes #224 + +Alexander Lamaison (13 May 2012) +- Prevent sftp_packet_read accessing freed memory. + + sftp_packet_add takes ownership of the packet passed to it and (now that we + handle zombies) might free the packet. sftp_packet_read uses the packet type + byte as its return code but by this point sftp_packet_add might have freed + it. This change fixes the problem by caching the packet type before calling + sftp_packet_add. + + I don't understand why sftp_packet_read uses the packet type as its return + code. A future change might get rid of this entirely. + +Daniel Stenberg (12 May 2012) +- sftp_packet_flush: flush zombies too + + As this function is called when the SFTP session is closed, it needs to + also kill all zombies left in the SFTP session to avoid leaking memory + just in case some zombie would still be in there. + +- sftp_packetlist_flush: zombies must not have responses already + + When flushing the packetlist, we must only add the request as a zombie + if no response has already been received. Otherwise we could wrongly + make it a zombie even though the response was already received and then + we'd get a zombie stuck there "forever"... + +- sftp_read: on EOF remove packet before flush + + Since the sftp_packetlist_flush() function will move all the existing + FXP_READ requests in this handle to the zombie list we must first remove + this just received packet as it is clearly not a zombie. + +- sftp_packet_require: sftp_packet_read() returning 0 is not an error + + Exactly as the comment in the code said, checking the return code from + sftp_packet_read() with <= was wrong and it should be < 0. With the new + filtering on incoming packets that are "zombies" we can now see this + getting zero returned. + +- sftp_packetlist_flush: only make it zombie if it was sent + + The list of outgoing packets may also contain packets that never were + sent off and we better not make them zombies too. + +- [Alexander Lamaison brought this change] + + Mark outstanding read requests after EOF as zombies. + + In order to be fast, sftp_read sends many read requests at once. With a small + file, this can mean that when EOF is received back, many of these requests are + still outstanding. Responses arriving after we close the file and abandon the + file handle are queued in the SFTP packet queue and never collected. This + causes transfer speed to drop as a progressively longer queue must be searched + for every packet. + + This change introduces a zombie request-ID list in the SFTP session that is + used to recognise these outstanding requests and prevent them being added to + the queue. + +Peter Stuge (23 Apr 2012) +- [Rafael Kitover brought this change] + + Update win32/GNUmakefile to use OpenSSL 1.0.1a + + libcrypto on win32 now depends on gdi32.dll, so move the OpenSSL LDLIBS + block to before the compiler definitions, so that libcrypto gets added + first, and then add -lgdi32 into the following common LDLIBS for gcc. + +Guenter Knauf (23 Apr 2012) +- Changed 'Requires' to 'Requires.private'. + + Only static builds need to link against the crypto libs. + +- Fixed 'Requires:' names. + + The 'Requires:' line lists the names of the .pc files. + +- Added 'Requires:' line to libssh2.pc. + + This is necessary so that other libs which lookup libssh2 info + via pkg-config can add the right crypto lib dependencies. + +- Updated dependency lib versions. + +Peter Stuge (18 Apr 2012) +- configure.ac: Add option to disable build of the example applications + + Examples are built by default. Any of the following options on the + configure command line will skip building them: + + --disable-examples-build + --enable-examples-build=no + --enable-examples-build=false + +- userauth.c: fread() from public key file to correctly detect any errors + + If the filename parameter for file_read_publickey() was the name of a + directory instead of a file then libssh2 would spin trying to fgetc() + from the FILE * for the opened directory when trying to determine the + length of the encoded public key, since fgetc() can't report errors. + + Use fread() instead to correctly detect this error condition along + with many others. + + This fixes the problem reported in + http://www.libssh2.org/mail/libssh2-devel-archive-2012-04/0021.shtml + + Reported-by: Oleksiy Zagorskyi + +- Return LIBSSH2_ERROR_SOCKET_DISCONNECT on EOF when reading banner + +Guenter Knauf (17 Apr 2012) +- Fixed copyright year. + +- Updated dependency lib versions in static makefiles. + +Daniel Stenberg (6 Apr 2012) +- version: bump to 1.4.2 + + We're on the 1.4.2 track now (at least) + +Version 1.4.1 (4 Apr 2012) + +Daniel Stenberg (4 Apr 2012) +- RELEASE-NOTES: updated for 1.4.1 release + +- always do "forced" window updates + + When calling _libssh2_channel_receive_window_adjust() internally, we now + always use the 'force' option to prevent libssh2 to avoid sending the + update if the update isn't big enough. + + It isn't fully analyzed but we have seen corner cases which made a + necessary window update not get send due to this and then the other side + doesn't send data our side then sits waiting for forever. + +- channel_read: force window adjusts! + + if there's not enough room to receive the data that's being requested, + the window adjustment needs to be sent to the remote and thus the force + option has to be used. _libssh2_channel_receive_window_adjust() would + otherwise "queue" small window adjustments for a later packet but that + is really terribly for the small buffer read that for example is the + final little piece of a very large file as then there is no logical next + packet! + + Reported by: Armen Babakhanian + Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2012-03/0130.shtml + +- [Paul Howarth brought this change] + + aes: the init function fails when OpenSSL has AES support + + The internal init function only worked fine when the configure script + didn't detect the OpenSSL AES_CTR function! + + Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2012-03/0111.shtml + Reported by: Paul Howarth + +- [Matthew Booth brought this change] + + transport_send: Finish in-progress key exchange before sending data + + _libssh2_channel_write() first reads outstanding packets before writing + new data. If it reads a key exchange request, it will immediately start + key re-exchange, which will require sending a response. If the output + socket is full, this will result in a return from + _libssh2_transport_read() of LIBSSH2_ERROR_EAGAIN. In order not to block + a write because there is no data to read, this error is explicitly + ignored and the code continues marshalling a packet for sending. When it + is sent, the remote end immediately drops the connection because it was + expecting a continuation of the key exchange, but got a data packet. + + This change adds the same check for key exchange to + _libssh2_transport_send() that is in _libssh2_transport_read(). This + ensures that key exchange is completed before any data packet is sent. + +- channel_write: acknowledge transport errors + + When draining data off the socket with _libssh2_transport_read() (which + in turn has to be done so that we can be sure to have read any possible + window-increasing packets), this code previously ignored errors which + could lead to nasty loops. Now all error codes except EAGAIN will cause + the error to be returned at once. + + Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2012-03/0068.shtml + Reported by: Matthew Booth + +- [Steven Dake brought this change] + + In examples/x11.c, Make sure sizeof passed to read operation is correct + + sizeof(buf) expands to 8 or 4 (since its a pointer). This variable may + have been static in the past, leading to this error. + + Signed-off-by: Steven Dake + +- [Steven Dake brought this change] + + Fix suspicious sizeof usage in examples/x11.c + + In the x11 example, sizeof(buf) = 8UL (on x86_64), when this should + probably represent the buffer size available. I am not sure how to + test that this change is actually correct, however. + + Signed-off-by: Steven Dake + +- sftp_packet_read: follow-up fix for EAGAIN/window adjust + + The commit in 7194a9bd7ba45 wasn't complete. This change makes sure + variables are initialized properly before used in the EAGAIN and window + adjust cases. + +- sftp_packet_add: use named error code instead of number + +- sftp_packet_add: verify the packet before accepting it + + In order to bail out as quickly as possible when things are wrong and + out of sync, make sure the SFTP message is one we understand. + +- SFTP: preserve the original error code more + + Lots of places in the code translated the original error into the more + generic LIBSSH2_ERROR_SOCKET_TIMEOUT but this turns out to distort the + original error reason a lot and makes tracking down the real origin of a + problem really hard. This change makes the original error code be + preserved to a larger extent when return up to the parent function. + +- sftp_packet_read: adjust window size as necessary + + Commit 03ca9020756 tried to simplify the window sizing logic but broke + SFTP readdir as there was no window sizing code left there so large + directory listings no longer worked. + + This change introduces window sizing logic to the sftp_packet_read() + function so that it now tells the remote about the local size having a + window size that suffice when it is about to ask for directory data. + + Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2012-03/0069.shtml + Reported by: Eric + +- [Steven Dake brought this change] + + Tell C compiler we don't care about return code of libssh2_init + + The call of libssh2_init returns a return code, but nothing could be done + within the _libssh2_init_if_needed execution path. + + Signed-off-by: Steven Dake + +- [Steven Dake brought this change] + + Add comment indicating a resource leak is not really a resource leak + + While possibly obvious to those investigating the code, coverity complains + about this out of scope leak. + + Signed-off-by: Steven Dake + +- [Steven Dake brought this change] + + Use safer snprintf rather then sprintf in scp_send() + + Signed-off-by: Steven Dake + +- [Steven Dake brought this change] + + Use safer snprintf rather then sprintf in scp_recv() + + While the buffer is indeed allocated to a safe length, better safe then sorry. + + Signed-off-by: Steven Dake + +- [Steven Dake brought this change] + + use snprintf in knownhost_writeline() rather then sprintf + + Although the function checks the length, if the code was in error, there + could potentially be a buffer overrun with the use of sprintf. Instead replace + with snprintf. + + Signed-off-by: Steven Dake + +- [Steven Dake brought this change] + + Add tracing to print packets left on session at libssh2_session_free + + Signed-off-by: Steven Dake + +Peter Stuge (2 Mar 2012) +- Define and use LIBSSH2_INVALID_SOCKET instead of INVALID_SOCKET + + INVALID_SOCKET is a special value in Windows representing a + non-valid socket identifier. We were #defining this to -1 on + non-Windows platforms, causing unneccessary namespace pollution. + Let's have our own identifier instead. + + Thanks to Matt Lawson for pointing this out. + +- nw/Makefile.netware: Fix project name typo to avoid needless confusion + +- example/x11: Set raw terminal mode manually instead of with cfmakeraw() + + OpenSolaris has no cfmakeraw() so to make the example more portable + we simply do the equivalent operations on struct termios ourselves. + + Thanks to Tom Weber for reporting this problem, and finding a solution. + +Daniel Stenberg (17 Feb 2012) +- sftp_write: cannot return acked data *and* EAGAIN + + Whenever we have acked data and is about to call a function that *MAY* + return EAGAIN we must return the number now and wait to get called + again. Our API only allows data *or* EAGAIN and we must never try to get + both. + +Peter Stuge (13 Feb 2012) +- example/x11: Build only when sys/un.h is found by configure + + The example can't be built on systems without AF_UNIX sockets. + +Daniel Stenberg (10 Feb 2012) +- [Alexander Lamaison brought this change] + + Simplified sftp_read. + + Removed the total_read variable that originally must have tracked how + much data had been written to the buffer. With non-blocking reads, we + must return straight away once we have read data into the buffer so this + variable served not purpose. + + I think it was still hanging around in case the initial processing of + 'leftover' data meant we wrote to the buffer but this case, like the + others, must return immediately. Now that it does, the last remaining + need for the variable is gone. + +- [Alexander Lamaison brought this change] + + Cleaned up sftp_read and added more explanation. + + Replaced the gotos which were implementing the state machine with + a switch statement which makes the states more explicit. + +- sftp_read: avoid data *and* EAGAIN + + Whenever we have data and is about to call a function that *MAY* return + EAGAIN we must return the data now and wait to get called again. Our API + only allows data *or* EAGAIN and we must never try to get both. + +Peter Stuge (2 Feb 2012) +- Add a tcpip-forward example which demonstrates remote port forwarding + +- libssh2.h: Add missing prototype for libssh2_session_banner_set() + +- example/subsystem_netconf.c: Return error when read buffer is too small + + Also remove a little redundancy in the read loop condition. + +- example/subsystem_netconf.c: Add a missing newline in an error message + +- Fix undefined reference to _libssh_error in libgcrypt backend + + Commit 209de22299b4b58e582891dfba70f57e1e0492db introduced a function + call to a non-existing function, and since then the libgcrypt backend + has not been buildable. + +Version 1.4.0 (31 Jan 2012) + +Daniel Stenberg (31 Jan 2012) +- RELEASE-NOTES: synced with 6bd584d29 for 1.4.0 + +- s/1.3.1/1.4.0 + + We're bumping the minor number + +- [Jernej Kovacic brought this change] + + libssh2_session_supported_algs: fix compiler warning + +- [Jernej Kovacic brought this change] + + session_supported_algs docs: added an example + +- [Gellule Xg brought this change] + + sftp-seek: clear EOF flag + + Set the EOF flag to False when calling seek64 to be able to get some + data back on a following read + +- [Peter Krempa brought this change] + + userauth: Provide more informations if ssh pub key extraction fails + + If the function that extracts/computes the public key from a private key + fails the errors it reports were masked by the function calling it. This + patch modifies the key extraction function to return errors using + _libssh_error() function. The error messages are tweaked to contain + reference to the failed operaton in addition to the reason. + + * AUTHORS: - add my name + * libgcrypt.c: _libssh2_pub_priv_keyfile(): - return a more verbose + error using + _libssh2_error() func. + * openssl.c: - modify call graph of _libssh2_pub_priv_keyfile() to use + _libssh2_error for error reporting(); + * userauth.c: - tweak functions calling _libssh2_pub_priv_keyfile() not + to shadow error messages + +- TODO: remove issues we (sort of) did already + +- ssh2_exec: skip error outputs for EAGAIN + + Since the example uses non-blocking mode, it will just flood the output + with this "nonsense" error. + +Guenter Knauf (30 Nov 2011) +- Some NetWare makefile tweaks. + +Daniel Stenberg (18 Nov 2011) +- LIBSSH2_SFTP_PACKET_MAXLEN: increase to 80000 + + Some SFTP servers send SFTP packets larger than 40000. Since the limit + is only present to avoid insane sizes anyway, we can easily bump it. + + The define was formerly in the public header libssh2_sftp.h but served + no external purpose and was moved into the source dir. + + Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2011-11/0004.shtml + Reported by: Michael Harris + +Alexander Lamaison (18 Nov 2011) +- [Peter Krempa brought this change] + + knownhost_check(): Don't dereference ext if NULL is passed + + Documentation for libssh2_knownhost_checkp() and related functions + states that the last argument is filled with data if non-NULL. + + "knownhost if set to non-NULL, it must be a pointer to a 'struct + libssh2_knownhost' pointer that gets filled in to point to info about a + known host that matches or partially matches." + + In this function ext is dereferenced even if set to NULL, causing + segfault in applications not needing the extra data. + +Daniel Stenberg (11 Nov 2011) +- [Peter Krempa brought this change] + + knownhost_add: Avoid dereferencing uninitialized memory on error path. + + In function knownhost_add, memory is alocated for a new entry. If normal + alocation is used, memory is not initialized to 0 right after, but a + check is done to verify if correct key type is passed. This test is done + BEFORE setting the memory to null, and on the error path function + free_host() is called, that tries to dereference unititialized memory, + resulting into a glibc abort(). + + * knownhost.c - knownhost_add(): - move typemask check before alloc + +- windows build: add define to avoid compiler warning + + A recent mingw compiler has started to complain on "#warning Please + include winsock2.h before windows.h" unless the magic define is set + first. + + Reported by: Vincent Torri + Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2011-10/0064.shtml + +Henrik Nordstrom (31 Oct 2011) +- [Vincent Torri brought this change] + + Correct Windows include file name case, simplifying cross-compilation + + When cross compiling to Windows, libssh2.h include Windows header files + with upper case filenames : BaseTsd.h and WinSock2.h. + + These files have lowercase names with mingw-w64 (iirc, it's the same with + mingw). And as on Windows, being lowercase or uppercase does not matter. + +Daniel Stenberg (25 Oct 2011) +- [Jernej Kovacic brought this change] + + libssh2_session_supported_algs: added + +- [Kamil Dudka brought this change] + + example/sftp_RW_nonblock: do not ignore LIBSSH2_ERROR_EAGAIN + + Bug: https://bugzilla.redhat.com/745420 + +Peter Stuge (5 Oct 2011) +- example/ssh2_agent: Print host key fingerprint before authentication + + Also moves the comment about not being authenticated to before the + agent authentication takes place, so that it better matches the code. + +Daniel Stenberg (29 Sep 2011) +- OpenSSL EVP: fix threaded use of structs + + Make sure we don't clear or reset static structs after first init so + that they work fine even when used from multiple threads. Init the + structs in the global init. + + Help and assistance by: John Engstrom + + Fixes #229 (again) + +- openssl: don't init static structs differently + + make_ctr_evp() is changed to take a struct pointer, and then each + _libssh2_EVP_aes_[keylen]_ctr function is made to pass in their own + static struct + + Reported by: John Engstrom + Fixes #229 + +Guenter Knauf (27 Sep 2011) +- Removed obsolete include path. + +Daniel Stenberg (21 Sep 2011) +- read_state: clear the state variable better + + Set read_state back to idle before trying to send anything so that if + the state somehow is wrongly set. + + Also, avoid such a case of confusion by resetting the read_state when an + sftp handle is closed. + +- sftp_read: remove leftover fprintf + + Reported by: Alexander Lamaison + +- sftp.h: fix the #ifdef to prevent multiple inclusions + +- sftp_read: use a state variable to avoid bad writes + + When a channel_write call has gotten an EAGAIN back, we try harder to + continue the same write in the subsequent invoke. + +- window_size: explicit adjustments only + + Removed the automatic window_size adjustments from + _libssh2_channel_read() and instead all channel readers must now make + sure to enlarge the window sizes properly themselves. + + libssh2_channel_read_ex() - the public function, now grows the window + size according to the requested buffer size. Applications can still opt + to grow the window more on demand. Larger windows tend to give higher + performance. + + sftp_read() now uses the read-ahead logic to figure out a window_size. + +- libssh2.h: bump the default window size to 256K + +- libssh2_userauth_keyboard_interactive.3: fix man warning + + It seemed to occur due to the excessive line length + +- [Mikhail Gusarov brought this change] + + Add missing .gitignore entries + +- [Mikhail Gusarov brought this change] + + Add manpage syntax checker to 'check' target + + In virtually every libssh2 release Debian's lintian catches syntax errors in + manpages. Prevent it by checking manpages as a part of testsuite. + +- libssh2_banner_set.3: fix nroff syntax mistake + +Guenter Knauf (10 Sep 2011) +- Use predefined resource compiler macro. + +- Added casts to silent compiler warnings. + +- Fixed uint64_t printf. + +- Fixed macro function signatures. + +- NetWare makefile tweaks. + +- Removed unused var. + +- Added 2 samples not mentioned. + +- Dont build x11 sample with MinGW. + +- Fixed executable file description. + +- Removed unused var. + +- Kill stupid gcc 3.x uninitialized warning. + +- Build all examples. + +- More MinGW makefile tweaks. + + Renamed *.mingw makefiles to GNUmakefile since GNU make picks these + up automatically, and therefore win32/Makefile removed. + +- Removed forgotten WINSOCK_VERSION defines. + +Daniel Stenberg (9 Sep 2011) +- libssh2_session_startup(3) => libssh2_session_handshake(3) + + Propagate for the current function in docs and examples. + libssh2_session_startup() is deprecated. + +- libssh2_banner_set => libssh2_session_banner_get + + Marked the old function as deprecated. Added the new name in the correct + name space with the same arguments and functionality. + +- new function: libssh2_session_banner_get + + Returns the banner from the server handshake + + Fixes #226 + +- libssh2.h: bump version to 1.4.0 for new function(s) + +- remove embedded CVS/svn tags + +- [liuzl brought this change] + + API add:libssh2_sftp_get_channel + + Return the channel of sftp, then caller can + control the channel's behavior. + + Signed-off-by: liuzl + +- _libssh2_channel_read: react on errors from receive_window_adjust + + Previously the function would ignore all errors except for EAGAIN. + +- sftp_read: extend and clarify the documentation + +- sftp_read: cap the read ahead maximum amount + + Now we only go up to LIBSSH2_CHANNEL_WINDOW_DEFAULT*30 bytes SFTP read + ahead, which currently equals 64K*30 == 1966080 bytes. + +- _libssh2_channel_read: fix non-blocking window adjusting + + If EAGAIN is returned when adjusting the receive window, we must not + read from the transport directly until we've finished the adjusting. + +Guenter Knauf (8 Sep 2011) +- Fix for systems which need sys/select.h. + +- The files were not gone but renamed ... + +Daniel Stenberg (6 Sep 2011) +- sftp_read: added documenting comment + + Taken from some recent email conversations I added some descriptions of + the logic in sftp_read() to aid readers. + +- 1.3.1: start the work + +Version 1.3.0 (6 Sep 2011) + +Daniel Stenberg (6 Sep 2011) +- Makefile.am: the Makefile.win32 files are gone + +- RELEASE-NOTES: updated for 1.3.0 + +- sftp_read: a short read is not end of file + + A returned READ packet that is short will now only reduce the + offset. + + This is a temporary fix as it is slightly better than the previous + approach but still not very good. + +- [liuzl brought this change] + + _libssh2_packet_add: adjust window size when truncating + + When receiving more data than what the window size allows on a + particular channel, make sure that the window size is adjusted in that + case too. Previously it would only adjust the window in the non-error + case. + +Guenter Knauf (29 Aug 2011) +- Silent compiler warning with MinGW64. + +- Fixed link to native Win32 awk tool. + +- Renamed MinGW makefiles. + +- Some MinGW makefile tweaks. + + Enable build without GNU tools and with MinGW64 compiler. + +- Fixed aes_ctr_do_cipher() signature. + +Daniel Stenberg (26 Aug 2011) +- [liuzl brought this change] + + libssh2_sftp_seek64: flush packetlist and buffered data + + When seeking to a new position, flush the packetlist and buffered data + to prevent already received or pending data to wrongly get used when + sftp-reading from the new offset within the file. + +- sftp_read: advance offset correctly for buffered copies + + In the case where a read packet has been received from the server, but + the entire contents couldn't be copied to the user-buffer, the data is + instead buffered and copied to the user's buffer in the next invocation + of sftp_read(). When that "extra" copy is made, the 'offset' pointer was + not advanced accordingly. + + The biggest impact of this flaw was that the 'already' variable at the + top of the function that figures out how much data "ahead" that has + already been asked for would slowly go more and more out of sync, which + could lead to the file not being read all the way to the end. + + This problem was most noticable in cases where the application would + only try to read the exact file size amount, like curl does. In the + examples libssh2 provides the sftp read function is most often called + with a fixed size large buffer and then the bug would not appear as + easily. + + This bug was introduced in the SFTP rewrite in 1.2.8. + + Bug: http://curl.haxx.se/mail/lib-2011-08/0305.html + http://www.libssh2.org/mail/libssh2-devel-archive-2011-08/0085.shtml + +- wrap some long lines < 80 columns + +- LIBSSH2_RECV: fix typo, use the RECV_FD macro + +- subsystem_netconf.c: fix compiler warnings + +- [Henrik Nordstrom brought this change] + + Custom callbacks for performing low level socket I/O + +- version bump: start working towards 1.3.0 + +Version 1.2.9 (16 Aug 2011) + +Daniel Stenberg (16 Aug 2011) +- RELEASE-NOTES: synced with 95d69d3a81261 + +- [Henrik Nordstrom brought this change] + + Document prototypes for macro defined functions + +- [Henrik Nordstrom brought this change] + + Avoid reuse after free when closing X11 channels + +- _libssh2_channel_write: handle window_size == 0 better + + When about to send data on the channel and the window size is 0, we must + not just return 0 if the transport_read() function returned EAGAIN as it + then causes a busy-loop. + + Bug: http://libssh2.org/mail/libssh2-devel-archive-2011-08/0011.shtml + +- gettimeofday: fix name space pollution + + For systems without its own gettimeofday() implementation, we still must + not provide one outside our namespace. + + Reported by: Bill Segall + +Dan Fandrich (5 Aug 2011) +- libssh2.pc.in: Fixed spelling in pkgconfig file + +Peter Stuge (17 Jul 2011) +- example/subsystem_netconf.c: Add missing #include + +- example/subsystem_netconf.c: Discard ]]>]]> and return only XML response + +- example/subsystem_netconf.c: Fix uninitialized variable bug + +- example: Add subsystem_netconf.c + + This example demonstrates how to use libssh2 to send a request to + the NETCONF subsystem available e.g. in JunOS. + + See also http://tools.ietf.org/html/draft-ietf-netconf-ssh-06 + +Daniel Stenberg (16 Jul 2011) +- man page cleanups: non-existing functions need no man pages + +- libssh2_new_host_entry.3: removed + + This is just junk leftovers. + +- userauth_keyboard_interactive: fix buffer overflow + + Partly reverse 566894494b4972ae12 which was simplifying the code far too + much and ended up overflowing a buffer within the LIBSSH2_SESSION + struct. Back to allocating the buffer properly like it used to do. + + Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2011-06/0032.shtml + Reported by: Alfred Gebert + +- keyboard-interactive man page: cleaned up + +- [Alfred Gebert brought this change] + + _libssh2_recv(): handle ENOENT error as EAGAIN + + A sftp session failed with error "failure establishing ssh session" on + Solaris and HP-UX. Sometimes the first recv() function call sets errno + to ENOENT. In the man pages for recv of Solaris and HP-UX the error + ENOENT is not documented. + + I tested Solaris SPARC and x86, HP-UX i64, AIX, Windows and Linux. + +- agent_list_identities: fix out of scope access + + An auto variable out of scope was being referenced and used. + + fixes #220 + +- _libssh2_wait_socket: fix timeouts for poll() uses + +- windows: inclusion fix + + include winsock2.h for all windows compilers + +- keyb-interactive: add the fixed buffer + + Belongs to commit 5668944 + +- code cleanup: don't use C99/c++ comments + + We aim for C89 compliance + +- keyb-interactive: allow zero length fields + + Allow zero length fields so they don't cause malloc(0) calls + + Avoid free()ing NULL pointers + + Avoid a malloc of a fixed 5 byte buffer. + +- libssh2_channel_process_startup.3: clean up + + Remove the references to the macro-fied shortcuts as they have their own + individual man pages. + + Made the prototype different and more readable. + +- man page: fix .BR lines + + We don't use \fI etc on .BR lines + +- userauth_keyboard_interactive: skip code on zero length auth + +- libssh2_channel_forward_accept.3: mention how to get error + + Since this returns a pointer, libssh2_session_last_errno() must be used + to get the actual error code and it wasn't that clear before. + +- timeout docs: mention they're added in 1.2.9 + +- sftp_write_sliding.c: indent fix + + Use the standard indenting and removed CVS leftover comment + +- [zl liu brought this change] + + sftp_write_sliding: send the complete file + + When reaching the end of file there can still be data left not sent. + +- [Douglas Masterson brought this change] + + session_startup: init state properly + + libssh2_session_startup() didn't set the state correctly so it could get + confused. + + Fixes #218 + +- timeout: added man pages + +- BLOCK_ADJUST_ERRNO: move rc to right level + + We can't declare the variable within the block and use it in the final + do-while() expression to be properly portable C89. + +- [Matt Lilley brought this change] + + adds a timeout to blocking calls + + Fixes bug #160 as per Daniel's suggestion + + Adds libssh2_session_set_timeout() and libssh2_session_get_timeout() + +- SCP: fix incorrect error code + + After an error occurs in libssh2_scp_recv() or libssh2_scp_send(), the + function libssh2_session_last_error() would return + LIBSSH2_ERROR_SOCKET_NONE on error. + + Bug: http://trac.libssh2.org/ticket/216 + Patch by: "littlesavage" + + Fixes #216 + +Guenter Knauf (19 Apr 2011) +- Updated default (recommended) dependency versions. + +Daniel Stenberg (17 Apr 2011) +- libssh2_session_block_directions: fix mistake + + The last LIBSSH2_SESSION_BLOCK_INBOUND should be + LIBSSH2_SESSION_BLOCK_OUTBOUND + + And I shortened the short description + + Reported by: "drswinghead" + +- msvcproj: added libs and debug stuff + + Added libraries needed to link whether using openssl dynamically or + statically + + Added LIBSSH2DEBUG define to debug versions to enable tracing + + URL: http://trac.libssh2.org/ticket/215 + Patch by: Mark Smith + +- sftp_write: clean offsets on error + + When an error has occurred on FXP_WRITE, we must make sure that the + offset, sent offset and acked counter are reset properly. + +- example/.gitignore: ignore built binaries + +- sftp_write: flush the packetlist on error + + When an error occurs during write, flush the entire list of pending + outgoing SFTP packets. + +- keepalive: add first basic man pages + + Someone on IRC pointed out that we don't have these documented so I + wrote up a first set based on the information in the wiki: + http://trac.libssh2.org/wiki/KeepAlive + +- scp_write_nonblock.c: remove pointless check + + libssh2_channel_write() cannot return a value that is larger than the + input length value + +Mikhail Gusarov (9 Apr 2011) +- s/\.NF/.nf/ to fix wrong macro name caught by man --warnings + +Daniel Stenberg (6 Apr 2011) +- version: bump to 1.2.9_dev + + Also update the copyright year range to include 2011 + +- configure: fix $VERSION + + Stop using the $VERSION variable as it seems to be magically used by + autoconfig itself and thus gets set to the value set in AC_INIT() + without us wanting that. $LIBSSH2VER is now the libssh2 version as + detected. + + Reported by: Paul Howarth + Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2011-04/0008.shtml + +- maketgz: use git2news.pl by the correct name + +Version 1.2.8 (4 Apr 2011) + +Daniel Stenberg (4 Apr 2011) +- RELEASE-NOTES: synced with fabf1a45ee + +- NEWS: auto-generated from git + + Starting now, the NEWS file is generated from git using the git2news.pl + script. This makes it always accurate and up-to-date, even for daily + snapshots etc. + +- sftp_write: handle FXP_WRITE errors + + When an sftp server returns an error back on write, make sure the + function bails out and returns the proper error. + +- configure: stop using the deprecated AM_INIT_AUTOMAKE syntax + +Alexander Lamaison (13 Mar 2011) +- Support unlimited number of host names in a single line of the known_hosts file. + + Previously the code assumed either a single host name or a hostname,ip-address pair. However, according to the spec [1], there can be any number of comma separated host names or IP addresses. + + [1] http://www.openbsd.org/cgi-bin/man.cgi?query=sshd&sektion=8 + +Daniel Stenberg (26 Feb 2011) +- libssh2_knownhost_readfile.3: clarify return value + + This function returns the number of parsed hosts on success, not just + zero as previously documented. + +Peter Stuge (26 Feb 2011) +- Don't save allocated packet size until it has actually been allocated + + The allocated packet size is internal state which needs to match reality + in order to avoid problems. This commit fixes #211. + +Daniel Stenberg (21 Feb 2011) +- [Alfred Gebert brought this change] + + session_startup: manage server data before server identification + + Fix the bug that libssh2 could not connect if the sftp server + sends data before sending the version string. + + http://tools.ietf.org/html/rfc4253#section-4.2 + + "The server MAY send other lines of data before sending the version + string. Each line SHOULD be terminated by a Carriage Return and Line + Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded + in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients + MUST be able to process such lines." + +- [Alfred Gebert brought this change] + + fullpacket: decompression only after init + + The buffer for the decompression (remote.comp_abstract) is initialised + in time when it is needed. With this fix decompression is disabled when + the buffer (remote.comp_abstract) is not initialised. + + Bug: http://trac.libssh2.org/ticket/200 + +- _libssh2_channel_read: store last error + + When the transport layer returns EAGAIN this function didn't call + _libssh2_error() which made the last_error not get set. + +- sftp_write: clarified the comment header + +- sftp_read: avoid wrapping counter to insanity + + As pointed out in bug #206, if a second invoke of libssh2_sftp_read() + would shrink the buffer size, libssh2 would go nuts and send out read + requests like crazy. This was due to an unsigned variable turning + "negative" by some wrong math, and that value would be the amount of + data attempt to pre-buffer! + + Bug: http://trac.libssh2.org/ticket/206 + +- sftp_packet_read: use 32bit variables for 32bit data + +- libssh2_sftp_stat_ex.3: cleaned up, extended + + Removed the macros from it as they have their own man pages. + + Added the LIBSSH2_SFTP_ATTRIBUTES struct in here for easier reference. + +- sftp_readdir: return error if buffer is too small + + If asked to read data into a buffer and the buffer is too small to hold + the data, this function now returns an error instead of as previously + just copy as much as fits. + +- sftp_symlink: return error if receive buffer too small + + and clean up some variable type mismatches + + Discussion: http://www.libssh2.org/mail/libssh2-devel-archive-2011-01/0001.shtml + +- docs: clarify what happens with a too small buffer + + This flaw is subject to change, but I figured it might be valuable to + users of existing code to know how it works. + +- channel_request_pty_size: fix reqPTY_state + + The state variable isn't properly set so every other call to the + function fails! + + Bug: http://libssh2.org/mail/libssh2-devel-archive-2010-12/0096.shtml + Reported by: Steve Legg + +- data size: cleanup + + Fix 64bit warnings by using (s)size_t and dedicated uint32_t types more. + +- [Pierre Joye brought this change] + + ssize_t: proper typedef with MSVC compilers + + As discussed on the mailing list, it was wrong for win64 and using the + VC-provided type is the safest approach instead of second- guessing + which one it should be. + +Guenter Knauf (22 Dec 2010) +- Updated OpenSSL version. + +- Expanded tabs to spaces. + +Peter Stuge (21 Dec 2010) +- [Joey Degges brought this change] + + _libssh2_ntohu64: fix conversion from network bytes to uint64 + + Cast individual bytes to uint64 to avoid overflow in arithmetic. + +Daniel Stenberg (20 Dec 2010) +- libssh2_userauth_list: language fix + + "faily" is not a good English word, and I also cleaned up some other minor + mistakes + +- crypto: unify the generic functions + + Added crypto.h that is the unified header to include when using crypto + functionality. It should be the only header that needs to adapt to the + underlying crypto library in use. It provides the set of prototypes that + are library agnostic. + +- [Mark Smith brought this change] + + userauth: derive publickey from private + + Pass a NULL pointer for the publickey parameter of + libssh2_userauth_publickey_fromfile and + libssh2_userauth_hostbased_fromfile functions. In this case, the + functions recompute the public key from the private key file data. + + This is work done by Jean-Louis CHARTON + , then adapted by Mark Smith and + slightly edited further by me Daniel. + + WARNING: this does leave the feature NOT WORKING when libssh2 is built + to use libgcrypt instead of OpenSSL simply due to lack of + implementation. + +- ssh2_echo: Value stored to 'exitcode' is never read + +- _libssh2_packet_add: fix SSH_MSG_DEBUG weirdness + + I believe I may have caused this weird typo style error when I cleaned + up this function a while ago. Corrected now. + +- uint32: more longs converted to proper types + + I also moved the MAC struct over to the mac.h header file and made sure + that the users of that struct include that file. + +- SFTP: more types to uint32_t + + The 'num_names' field in the SSH_FXP_NAME response is an unsigned 32bit + value so we make sure to treat it like that. + +- SFTP: request_ids are uint32_t + + I went over the code and made sure we use uint32_t all over for the + request_id data. It is an unsigned 32bit value on the wire. + +- SFTP: store request_id separately in packets + + By using a new separate struct for incoming SFTP packets and not sharing + the generic packet struct, we can get rid of an unused field and add a + new one dedicated for holding the request_id for the incoming + package. As sftp_packet_ask() is called fairly often, a "mere" integer + comparison is MUCH faster than the previous memcmp() of (typically) 5 + bytes. + +- libssh2_sftp_open_ex: man page extended and cleaned up + + I added the missing documentation for the 'flags' argument. + +- SFTP: unify the READ/WRITE chunk structs + +- SFTP: fix memory leaks + + Make sure that we cleanup remainders when the handle is closed and when + the subsystem is shutdown. + + Existing flaw: if a single handle sends packets that haven't been + replied to yet at the time when the handle is closed, those packets will + arrive later and end up in the generic packet brigade queue and they + will remain in there until flushed. They will use unnecessary memory, + make things slower and they will ruin the SFTP handling if the + request_id counter ever wraps (highly unlikely to every happen). + +- sftp_close_handle: packet list is generic + + Fix comment, simplify the loop logic + +- sftp_read: pipeline reads + + The SFTP read function now does transfers the same way the SFTP write + function was made to recently: it creates a list of many outgoing + FXP_READ packets that each asks for a small data chunk. The code then + tries to keep sending read request while collecting the acks for the + previous requests and returns the received data. + +- sftp_write: removed unused variable + +- _libssh2_channel_close: don't call transport read if disconnected + + The loop that waits for remote.close to get set may end up looping + forever since session->socket_state gets set to + LIBSSH2_SOCKET_DISCONNECTED by the packet_add() function called from the + transport_read() function and after having been set to + LIBSSH2_SOCKET_DISCONNECTED, the transport_read() function will only + return 0. + + Bug: http://trac.libssh2.org/ticket/198 + +- libssh2_sftp_seek64: new man page + + Split off libssh2_sftp_seek64 from the libssh2_sftp_seek man page, and + mentioned that we consider the latter deprecated. Also added a mention + about the dangers of doing seek during writing or reading. + +- sftp_seek: fix + + The new SFTP write code caused a regression as the seek function no + longer worked as it didn't set the write position properly. + + It should be noted that seeking is STRONGLY PROHIBITED during upload, as + the upload magic uses two different offset positions and the multiple + outstanding packets etc make them sensitive to change in the midst of + operations. + + This functionality was just verified with the new example code + sftp_append. This bug was filed as bug #202: + + Bug: http://trac.libssh2.org/ticket/202 + +- sftp_append: new example doing SFTP append + +- MAX_SFTP_OUTGOING_SIZE: 30000 + + I ran SFTP upload tests against localhost. It showed that to make the + app reach really good speeds, I needed to do a little code tweak and + change MAX_SFTP_OUTGOING_SIZE from 4000 to 30000. The tests I did before + with the high latency tests didn't show any real difference whatever I + had that size set to. + + This number is the size in bytes that libssh2 cuts off the large input + buffer and sends off as an individual sftp packet. + +- sftp_write_sliding.c: new example + + This is an example that is very similar to sftp_write_nonblock.c, with + the exception that this uses + + 1 - a larger upload buffer + + 2 - a sliding buffer mechnism to allow the app to keep sending lots of + data to libssh2 without having to first drain the buffer. + + These are two key issues to make libssh2 SFTP uploads really perform + well at this point in time. + +- cpp: s/#elsif/#elif + + This looks like a typo as #elsif is not really C... + +- _libssh2_channel_write: revert channel_write() use + + The attempts made to have _libssh2_channel_write() accept larger pieces + of data and split up the data by itself into 32700 byte chunks and pass + them on to channel_write() in a loop as a way to do faster operations on + larger data blocks was a failed attempt. + + The reason why it is difficult: + + The API only allows EAGAIN or a length to be returned. When looping over + multiple blocks to get sent, one block can get sent and the next might + not. And yet: when transport_send() has returned EAGAIN we must not call + it again with new data until it has returned OK on the existing data it + is still working on. This makes it a mess and we do get a much easier + job by simply returning the bytes or EAGAIN at once, as in the EAGAIN + case we can assume that we will be called with the same arguments again + and transport_send() will be happy. + + Unfortunately, I think we take a small performance hit by not being able + to do this. + +- ssh2_echo: new example + + This is a new example snippet. The code is largely based on ssh2_exec, + and is written by Tommy Lindgren. I edited it into C90 compliance and to + conform to libssh2 indent style and some more. + +- send_existing: return after send_existing + + When a piece of data is sent from the send_existing() function we must + make the parent function return afterwards. Otherwise we risk that the + parent function tries to send more data and ends up getting an EGAIN for + that more data and since it can only return one return code it doesn't + return info for the successfully sent data. + + As this change is a regression I now added a larger comment explaining + why it has to work like this. + +- _libssh2_channel_write: count resent data as written + + In the logic that resends data that was kept for that purpose due to a + previous EAGAIN, the data was not counted as sent causing badness. + +Peter Stuge (13 Nov 2010) +- Use fprintf(stderr, ) instead of write(2, ) for debugging + +- session/transport: Correctly handle when _libssh2_send() returns -EAGAIN + +- src/agent.c: Simplify _libssh2_send() error checking ever so slightly + +Daniel Stenberg (12 Nov 2010) +- send/recv: use _libssh2_recv and _libssh2_send now + + Starting now, we unconditionally use the internal replacement functions + for send() and recv() - creatively named _libssh2_recv() and + _libssh2_send(). + + On errors, these functions return the negative 'errno' value instead of + the traditional -1. This design allows systems that have no "natural" + errno support to not have to invent it. It also means that no code + outside of these two transfer functions should use the errno variable. + +- channel_write: move some logic to _libssh2_channel_write + + Some checks are better done in _libssh2_channel_write just once per + write instead of in channel_write() since the looping will call the + latter function multiple times per _libssh2_channel_write() invoke. + +- sftp_write: handle "left over" acked data + + The SFTP handle struct now buffers number of acked bytes that haven't + yet been returned. The way this is used is as following: + + 1. sftp_write() gets called with a buffer of let say size 32000. We + split 32000 into 8 smaller packets and send them off one by one. One of + them gets acked before the function returns so 4000 is returned. + + 2. sftp_write() gets called again a short while after the previous one, + now with a much smaller size passed in to the function. Lets say 8000. + In the mean-time, all of the remaining packets from the previous call + have been acked (7*4000 = 28000). This function then returns 8000 as all + data passed in are already sent and it can't return any more than what + it got passed in. But we have 28000 bytes acked. We now store the + remaining 20000 in the handle->u.file.acked struct field to add up in + the next call. + + 3. sftp_write() gets called again, and now there's a backlogged 20000 + bytes to return as fine and that will get skipped from the beginning + of the buffer that is passed in. + +- sftp_write: polished and simplified + + Removed unnecessary struct fields and state changes within the function. + + Made the loop that checks for ACKs only check chunks that were fully + sent. + +- SCP: on failure, show the numerical error reason + + By calling libssh2_session_last_errno() + +- SFTP: provide the numerical error reason on failure + +- SCP: clean up failure treatment + + When SCP send or recv fails, it gets a special message from the server + with a warning or error message included. We have no current API to + expose that message but the foundation is there. Removed unnecessary use + of session struct fields. + +- sftp_write: enlarge buffer to perform better + +- packets: code cleanup + + I added size checks in several places. I fixed the code flow to be easier + to read in some places. + + I removed unnecessary zeroing of structs. I removed unused struct fields. + +- LIBSSH2_CALLBACK_MACERROR: clarify return code use + +- _libssh2_userauth_publickey: avoid shadowing + +- packet: avoid shadowing global symbols + +- sftp_readdir: avoid shadowing + +- shadowing: don't shadow the global compress + +- _libssh2_packet_add: turn ifs into a single switch + +- _libssh2_packet_add: check SSH_MSG_GLOBAL_REQUEST packet + +- _libssh2_packet_add: SSH_MSG_DEBUG length checks + + Verify lengths before using them. Read always_display from the correct + index. Don't copy stuff around just to provide zero-termination of the + strings. + +- _libssh2_packet_add: SSH_MSG_IGNORE skip memmove + + There's no promise of a zero termination of the data in the callback so + no longer perform ugly operation in order to provide it. + +- _libssh2_packet_add: SSH_MSG_DISCONNECT length checks + + Verify lengths before trying to read data. + +- indent: break lines at 80 columns + +- SSH_MSG_CHANNEL_OPEN_FAILURE: used defined values + + We don't like magic numbers in the code. Now the acceptable failure + codes sent in the SSH_MSG_CHANNEL_OPEN_FAILURE message are added as + defined values in the private header file. + +- sftp_write: don't return EAGAIN if no EAGAIN was received + + This function now only returns EAGAIN if a lower layer actually returned + EAGAIN to it. If nothing was acked and no EAGAIN was received, it will + now instead return 0. + +- _libssh2_wait_socket: detect nothing-to-wait-for + + If _libssh2_wait_socket() gets called but there's no direction set to + wait for, this causes a "hang". This code now detects this situation, + set a 1 second timeout instead and outputs a debug output about it. + +- decomp: remove the free_dest argument + + Since the decompress function ALWAYS returns allocated memory we get a + lot simpler code by removing the ability to return data unallocated. + +- decomp: cleaned off old compression stuff + + I cleared off legacy code from when the compression and decompression + functions were a single unified function. Makes the code easier to read + too. + +- [TJ Saunders brought this change] + + decomp: increase decompression buffer sizes + +- [TJ Saunders brought this change] + + zlib: Add debug tracing of zlib errors + +- sftp_packet_read: handle partial reads of the length field + + SFTP packets come as [32 bit length][payload] and the code didn't + previously handle that the initial 32 bit field was read only partially + when it was read. + +- [Jasmeet Bagga brought this change] + + kex_agree_hostkey: fix NULL pointer derefence + + While setting up the session, ssh tries to determine the type of + encryption method it can use for the session. This requires looking at + the keys offered by the remote host and comparing these with the methods + supported by libssh2 (rsa & dss). To do this there is an iteration over + the array containing the methods supported by libssh2. + + If there is no agreement on the type of encryption we come to the 3rd + entry of the hostkeyp array. Here hostkeyp is valid but *hostkep is + NULL. Thus when we dereference that in (*hostkeyp)->name there is a + crash + +- _libssh2_transport_send: remove dead assignment + + 'data' isn't accessed beyond this point so there's no need to assign it. + +- scp_recv: remove dead assignment + + Instead of assigning a variable we won't read, we now use the more + explicit (void) prefix. + +- sftp_write: removed superfluous assignment + +- bugfix: avoid use of uninitialized value + +- sftp_packet_require: propagate error codes better + + There were some chances that they would cause -1 to get returned by + public functions and as we're hunting down all such occurances and since + the underlying functions do return valuable information the code now + passes back proper return codes better. + +- [Alfred Gebert brought this change] + + fix memory leaks (two times cipher_data) for each sftp session + +- libssh2_userauth_authenticated: make it work as documented + + The man page clearly says it returns 1 for "already authenticated" but + the code said non-zero. I changed the code to use 1 now, as that is also + non-zero but it gets the benefit that it now matches the documentation. + + Using 1 instead of non-zero is better for two reasons: + + 1. We have the opportunity to introduce other return codes in the future for + things like error and what not. + 2. We don't expose the internal bitmask variable value. + +- userauth_keyboard_interactive: fix indent + +- [Alfred Gebert brought this change] + + fix memory leak in userauth_keyboard_interactive() + + First I wanted to free the memory in session_free() but then + I had still memory leaks because in my test case the function + userauth_keyboard_interactive() is called twice. It is called + twice perhaps because the server has this authentication + methods available: publickey,gssapi-with-mic,keyboard-interactive + The keyboard-interactive method is successful. + +- dist: include sftp.h in dist archives + +Simon Josefsson (27 Oct 2010) +- Update header to match new function prototype, see c48840ba88. + +Daniel Stenberg (26 Oct 2010) +- bugfixes: the transport rearrange left some subtle flaws now gone + +- libssh2_userauth_publickey_fromfile_ex.3: cleaned up looks + +- libssh2_userauth_publickey: add man page + + I found an undocumented public function and we can't have it like + that. The description here is incomplete, but should serve as a template + to allow filling in... + +- libssh2_sftp_write.3: added blurb about the "write ahead" + + Documented the new SFTP write concept + +- sftp_close_handle: free any trailing write chunks + +- _libssh2_channel_write: fix warnings + +- SFTP: bufgix, move more sftp stuff to sftp.h + + The sftp_write function shouldn't assume that the buffer pointer will be + the same in subsequent calls, even if it assumes that the data already + passed in before haven't changed. + + The sftp structs are now moved to sftp.h (which I forgot to add before) + +- SFTP: use multiple outgoing packets when writing + + sftp_write was rewritten to split up outgoing data into multiple packets + and deal with the acks in a more asynchronous manner. This is meant to + help overcome latency and round-trip problems with the SFTP protocol. + +- TODO: implemented a lot of the ideas now + +- _libssh2_channel_write: removed 32500 size limit + + Neither _libssh2_channel_write nor sftp_write now have the 32500 size + limit anymore and instead the channel writing function now has its own + logic to send data in multiple calls until everything is sent. + +- send_existing: don't tell parent to return when drained + + That will just cause unnecessary code execution. + +- _libssh2_channel_write: general code cleanup + + simplified the function and removed some unused struct fields + +- _libssh2_transport_send: replaces _libssh2_transport_write + + The new function takes two data areas, combines them and sends them as a + single SSH packet. This allows several functions to allocate and copy + less data. + + I also found and fixed a mixed up use of the compression function + arguments that I introduced in my rewrite in a recent commit. + +- scp_write_nonblock: use select() instead of busyloop + + Make this example nicer by not busylooping. + +- send_existing: clear olen when the data is sent off + +- _libssh2_transport_write: allow 256 extra bytes around the packet + +- _libssh2_transport_write: remade to send without malloc + +- compress: compression disabled by default + + We now allow libssh2_session_flag() to enable compression with a new + flag and I added documentation for the previous LIBSSH2_FLAG_SIGPIPE + flag which I wasn't really aware of! + +- comp: split the compress function + + It is now made into two separate compress and decompress functions. In + preparation for upcoming further modficications. + +Dan Fandrich (20 Oct 2010) +- Added header file to allow compiling in older environments + +Daniel Stenberg (20 Oct 2010) +- TODO: add a possible new API for SFTP transfers + +- TODO: "New Transport API" added + +- TODO: add buffering plans + +Simon Josefsson (13 Oct 2010) +- Mention libssh2_channel_get_exit_signal and give kudos. + +- [Tommy Lindgren brought this change] + + Add libssh2_channel_get_exit_signal man page. + + Signed-off-by: Simon Josefsson + +- [Tommy Lindgren brought this change] + + Add libssh2_channel_get_exit_signal. + + Signed-off-by: Simon Josefsson + +- Add libssh2_free man page and fix typo. + +- Add libssh2_free. + +Daniel Stenberg (11 Oct 2010) +- scp_recv: improved treatment of channel_read() returning zero + + As a zero return code from channel_read() is not an error we must make + sure that the SCP functions deal with that properly. channel_read() + always returns 0 if the channel is EOFed already so we check for EOF + after 0-reads to be able to return error properly. + +- libssh2_session_methods.3: detail what can be asked for + +- compression: send zlib before none + + As the list of algorithms in a preferred order we should send zlib + before none to increase the chances that the server will let us do + compression. + +- compress: faster check, better return codes + + In the transport functions we avoid a strcmp() now and just check a + boolean instead. + + The compress/decompress function's return code is now acknowledged and + used as actual return code in case of failures. + +- libssh2_session_handshake: replaces libssh2_session_startup() + + The function libssh2_session_startup() is now considered deprecated due + to the portability issue with the socket argument. + libssh2_session_handshake() is the name of the replacement. + +- libssh2_socket_t: now externally visible + + In preparation for upcominig changes, the libssh2_socket_t type is now + typedef'ed in the public header. + +- _libssh2_transport_drain: removed + + This function proved not to be used nor useful. + +- _libssh2_channel_write: don't iterate over transport writes + + When a call to _libssh2_transport_write() succeeds, we must return from + _libssh2_channel_write() to allow the caller to provide the next chunk + of data. + + We cannot move on to send the next piece of data that may already have + been provided in this same function call, as we risk getting EAGAIN for + that and we can't return information both about sent data as well as + EAGAIN. So, by returning short now, the caller will call this function + again with new data to send. + +- _libssh2_transport_write: updated documentation blurb + +- _libssh2_transport_write: remove fprintf remainder + + Mistake from previous debugging + +- session: improved errors + + Replaced -1/SOCKET_NONE errors with appropriate error defines instead. + + Made the verbose trace output during banner receiving less annoying for + non-blocking sessions. + +- crypt_init: use correct error define + +- _libssh2_error: hide EAGAIN for non-blocking sessions + + In an attempt to make the trace output less cluttered for non-blocking + sessions the error function now avoids calling the debug function if the + error is the EAGAIN and the session is non-blocking. + +- agent: use better error defines + +- comp_method_zlib_init: use correct error defines + +- transport: better error codes + + LIBSSH2_SOCKET_NONE (-1) should no longer be used as error code as it is + (too) generic and we should instead use specific and dedicated error + codes to better describe the error. + +- channel: return code and _libssh2_error cleanup + + Made sure that all transport_write() call failures get _libssh2_error + called. + +- _libssh2_channel_write: limit to 32700 bytes + + The well known and used ssh server Dropbear has a maximum SSH packet + length at 32768 by default. Since the libssh2 design current have a + fixed one-to-one mapping from channel_write() to the packet size created + by transport_write() the previous limit of 32768 in the channel layer + caused the transport layer to create larger packets than 32768 at times + which Dropbear rejected forcibly (by closing the connection). + + The long term fix is of course to remove the hard relation between the + outgoing SSH packet size and what the input length argument is in the + transport_write() function call. + +- libssh.h: add more dedicated error codes + +- SCP: allow file names with bytes > 126 + + When parsing the SCP protocol and verifying that the data looks like a + valid file name, byte values over 126 must not be consider illegal since + UTF-8 file names will use such codes. + + Reported by: Uli Zappe + Bug: http://www.libssh2.org/mail/libssh2-devel-archive-2010-08/0112.shtml + +Dan Fandrich (25 Aug 2010) +- Document the three sftp stat constants + +Guenter Knauf (18 Aug 2010) +- Fixed Win32 makefile which was now broken at resource build. + +- It is sufficient to pipe stderr to NUL to get rid of the nasty messages. + +- [Author: Guenter Knauf brought this change] + + Removed Win32 ifdef completely for sys/uio.h. + + No idea why we had this ifdef at all but MSVC, MingW32, Watcom + and Borland all have no sys/uio.h header; so if there's another + Win32 compiler which needs it then it should be added explicitely + instead of this negative list. + +- New files should also be added to Makefile.am. + + Otherwise they will never be included with release and snapshot tarballs ... + +Daniel Stenberg (18 Aug 2010) +- version: bump to 1.2.8_DEV + +Version 1.2.7 (17 Aug 2010) + +Daniel Stenberg (17 Aug 2010) +- release: updated to hold 1.2.7 info + +Guenter Knauf (17 Aug 2010) +- Use the new libssh2.rc file. + +- Added resource file for libssh2.dll (shamelessly stolen from libcurl). + +- Updated Win32 MSVC dependencies versions. + +- Added include for sys/select.h to get fd.set on some platforms. + +- Added Watcom makefile borrowed from libcurl. + + This makefile compiles already all files fine for static lib, but needs + final touch when I have OpenSSL fully working with shared libs and Watcom. + +- Added copyright define to libssh2.h and use it for binary builds. + +- Moved version defines up in order to include from .rc file. + + Blocked rest of header with ifndef so its possible to let + the rc compiler only use the version defines. + +- Some minor makefile tweaks. + +Daniel Stenberg (2 Aug 2010) +- example: treat the libssh2_channel_read() return code properly + + A short read is not an error. Only negative values are errors! + +- libssh2_wait_socket: reset error code to "leak" EAGAIN less + + Since libssh2 often sets LIBSSH2_ERROR_EAGAIN internally before + _libssh2_wait_socket is called, we can decrease some amount of + confusion in user programs by resetting the error code in this function + to reduce the risk of EAGAIN being stored as error when a blocking + function returns. + +- _libssh2_wait_socket: poll needs milliseconds + + As reported on the mailing list, the code path using poll() should + multiple seconds with 1000 to get milliseconds, not divide! + + Reported by: Jan Van Boghout + +- typedef: make ssize_t get typedef without LIBSSH2_WIN32 + + The condition around the ssize_t typedef depended on both LIBSSH2_WIN32 + *and* _MSC_VER being defined when it should be enough to depend on + _MSC_VER only. It also makes it nicer so libssh2-using code builds fine + without having custom defines. + +- [John Little brought this change] + + session_free: free more data to avoid memory leaks + +- channel_free: ignore problems with channel_close() + + As was pointed out in bug #182, we must not return failure from + _libssh2_channel_free() when _libssh2_channel_close() returns an error + that isn't EAGAIN. It can effectively cause the function to never go + through, like it did now in the case where the socket was actually + closed but socket_state still said LIBSSH2_SOCKET_CONNECTED. + + I consider this fix the right thing as it now also survives other + errors, even if making sure socket_state isn't lying is also a good + idea. + +- publickey_list_free: no return value from a void function + + Fixed a compiler warning I introduced previously when checking input + arguments more. I also added a check for the other pointer to avoid NULL + pointer dereferences. + +- [Lars Nordin brought this change] + + openssl: make use of the EVP interface + + Make use of the EVP interface for the AES-funktion. Using this method + supports the use of different ENGINES in OpenSSL for the AES function + (and the direct call to the AES_encrypt should not be used according to + openssl.org) + +Peter Stuge (23 Jun 2010) +- [Tor Arntsen brought this change] + + Don't overflow MD5 server hostkey + + Use SHA_DIGEST_LENGTH and MD5_DIGEST_LENGTH in memcpy instead of hardcoded + values. An incorrect value was used for MD5. + +- Fix message length bugs in libssh2_debug() + + There was a buffer overflow waiting to happen when a debug message was + longer than 1536 bytes. + + Thanks to Daniel who spotted that there was a problem with the message + length passed to a trace handler also after commit + 0f0652a3093111fc7dac0205fdcf8d02bf16e89f. + +- Make libssh2_debug() create a correctly terminated string + + Also use FILE *stderr rather than fd 2, which can very well be something + completely different. + +Daniel Stenberg (23 Jun 2010) +- [TJ Saunders brought this change] + + handshake: Compression enabled at the wrong time + + In KEXINIT messages, the client and server agree on, among other + things, whether to use compression. This method agreement occurs + in src/kex.c's kex_agree_methods() function. However, if + compression is enabled (either client->server, server->client, or + both), then the compression layer is initialized in + kex_agree_methods() -- before NEWKEYS has been received. + + Instead, the initialization of the compression layer should + happen after NEWKEYS has been received. This looks to occur + insrc/kex.c's diffie_hellman_sha1(), which even has the comment: + + /* The first key exchange has been performed, + + switch to active crypt/comp/mac mode */ + + There, after NEWKEYS is received, the cipher and mac algorithms + are initialized, and that is where the compression should be + initialized as well. + + The current implementation fails if server->client compression is + enabled because most server implementations follow OpenSSH's + lead, where compression is initialized after NEWKEYS. Since the + server initializes compression after NEWKEYS, but libssh2 + initializes compression after KEXINIT (i.e. before NEWKEYS), they + are out of sync. + + Reported in bug report #180 + +- [TJ Saunders brought this change] + + userauth_hostbased_fromfile: packet length too short + + The packet length calculated in src/userauth.c's + userauth_hostbased_fromfile() function is too short by 4 bytes; + it forgets to add four bytes for the length of the hostname. + This causes hostbased authentication to fail, since the server + will read junk data. + + verified against proftpd's mod_sftp module + +- _libssh2_userauth_publickey: reject method names longer than the data + + This functions get the method length by looking at the first 32 + bit of data, and I now made it not accept method lengths that are + longer than the whole data set is, as given in the dedicated + function argument. + + This was detected when the function was given bogus public key + data as an ascii string, which caused the first 32bits to create + a HUGE number. + +- NULL resistance: make more public functions survive NULL pointer input + + Sending in NULL as the primary pointer is now dealt with by more + public functions. I also narrowed the userauth.c code somewhat to + stay within 80 columns better. + +- agent: make libssh2_agent_userauth() work blocking properly + + previously it would always work in a non-blocking manner + +Peter Stuge (17 Jun 2010) +- Fix underscore typo for 64-bit printf format specifiers on Windows + + Commit 49ddf447ff4bd80285f926eac0115f4e595f9425 was missing underscores. + +Daniel Stenberg (16 Jun 2010) +- libssh2_session_callback_set: extended the man page + +- [John brought this change] + + LIBSSH2_DEBUG: macro uses incorrect function variable + + The LIBSSH2_DEBUG macro, defined in libssh2_priv.h, incorrectly uses the + function variable ssh_msg_disconnect when it should use ssh_msg_debug. + + This shows that the LIBSSH2_CALLBACK_DEBUG callback never has worked... + +- warning: fix a compiler warning 'pointer differs in signedness' + + As reported in bug #177 + +- portability: introduce LIBSSH2_INT64_T_FORMAT for 64bit printf()s + + As pointed out in bug #177, some of the Windows compilers use + %I64 to output 64 bit variables with the printf family. + +- debug: avoid sending NULL to sprintf %s + + Via the _libssh2_debug() macro/function. Pointed out by john in bug report + +- sftp docs: show macro on macro page, only function on function page + + The individual man pages for macros now show the full convenience + macro as defined, and then the man page for the actual function + only shows the function. + +- code police: make the code use less than 80 columns + +- libssh2_channel_write_ex: remove macros, added wording on buffer size + +- libssh2_sftp_write: document buffer size and changed some ordering + +- libssh2_channel_write_stderr: show how the macro is defined + +- libssh2_channel_write: show how the macro is defined + +- SFTP: limit write() to not produce overly large packets + + sftp_write() now limits how much data it gets at a time even more + than before. Since this function creates a complete outgoing + packet based on what gets passed to it, it is crucial that it + doesn't create too large packets. + + With this method, there's also no longer any problem to use very + large buffers in your application and feed that to libssh2. I've + done numerous tests now with uploading data over SFTP using 100K + buffers and I've had no problems with that. + +- scp_write_nonblock: add transfer time info + + Using the same timing logic and output format as + sftp_write_nonblock allows us to very easily run benchmarks on + SCP vs SFTP uploads using libssh2. + +- sftp_write_nonblock: select() on socket, use *BIG* buffer, time transfer + + The select() is just to make it nicer so that it doesn't + crazy-loop on EAGAIN. The buffer size thing is mostly to verify + that this really work as supposed. + + Transfer timing is just a minor thing, but it can just as well be + there and help us time and work on performance easier using out + of the box examples. + +- agent: use _libssh2_error() when returning errors + + As pointed out in bug report #173, this module basically never + used _libssh2_error() which made it work inconstently with other + parts of the libssh2 code base. This is my first take at making + this code more in line with the rest. + +- inputchecks: make lots of API functions check for NULL pointers + + If an application accidentally provides a NULL handle pointer to + the channel or sftp public functions, they now return an error + instead of segfaulting. + +- libssh2_channel_eof: clarify that it returns negative on errors + +- SFTP: keep the sftp error code as 32 bit + + 'last_errno' holds to the error code from the SFTP protocol and + since that is 32 bits on the wire there's no point in using a + long for this internally which is larger on some platforms. + +- agent: make the code better deal with unexpected code flows + + agent->ops gets initialized by the libssh2_agent_connect() call + but we need to make sure that we don't segfault even if a bad + sequence of function calls is used. + +Alexander Lamaison (10 Jun 2010) +- Better handling of invalid key files. + + Passing an invalid public key to libssh2_userauth_publickey_fromfile_ex + triggered an assertion. Replaced this with a runtime check that rejects + obviously invalid key data. + +Daniel Stenberg (10 Jun 2010) +- version: we start working on 1.2.7 now + +Version 1.2.6 (10 Jun 2010) + +Daniel Stenberg (10 Jun 2010) +- NEWS: add the 1.2.6 release details + +- RELEASE-NOTES: 1.2.6 details added + +Guenter Knauf (10 Jun 2010) +- fixed libssh2.dsw to use the generated libssh2.dsp; removed old *.dsp files. + +- moved MSVC strdup define to libssh2_config.h which we include already. + +- added missing source files to src/NMakefile. + +Daniel Stenberg (8 Jun 2010) +- libssh2_poll: refer to poll(3) and select(3) instead + +- example: fix strdup() for MSVC compiles + + MSVC has a _strdup() that we better use. This was reported in bug + +- SFTP: fail init SFTP if session isn't authenticated + + Alexander Lamaison filed bug #172 + (http://trac.libssh2.org/ticket/172), and pointed out that SFTP + init would do bad if the session isn't yet authenticated at the + time of the call, so we now check for this situation and returns + an error if detected. Calling sftp_init() at this point is bad + usage to start with. + +- direct_tcpip: bring back inclusion of libssh2_config.h + + In order to increase portability of this example, I'm bringing + the inclusion of libssh2_config.h back, and I also added an + require that header for this example to compile. + + I also made all code lines fit within 80 columns. + +Guenter Knauf (3 Jun 2010) +- cast away a warning. + +- moved CRT_SECURE_NO_DEPRECATE define up so its defined before the winsock headers are included. + +- fixed platform detection for MingW32 test makefile. + +- MingW32 has gettimeofday() implemented, so proper ifdef this function here. + +- removed MSVC ifdef since seems we can use __int64 still with latest headers. + +- changed copyright notice for MinW32 and NetWare binaries. + +- cleaned up MSVC ifdefs which where spreaded over 3 places. + +- added uint8_t typedef for NetWare CLIB platform. + +- if the function declaration gets changed the header should be changed too. + +- this is MSVC specific and doesnt apply for all Win32 compilers; + the uint8_t typedef clashes with MingW32 headers. + +- updated MingW32 makefiles for latest dependency lib versions. + +- updated NetWare makefiles for latest dependency lib versions. + +Dan Fandrich (30 May 2010) +- Fixed compiling with libgcrypt + + A change of parameter types from unsigned long to size_t was + missed in the prototype in libgcrypt.h + +Daniel Stenberg (28 May 2010) +- statvfs: use libssh2_sftp_statvfs only, no "_ex" + + As the long-term goal is to get rid of the extensive set of + macros from the API we can just as well start small by not adding + new macros when we add new functions. Therefore we let the + function be libssh2_sftp_statvfs() plainly without using an _ex + suffix. + + I also made it use size_t instead of unsigned int for the string + length as that too is a long-term goal for the API. + +- [Grubsky Grigory brought this change] + + DSP: output lib name typo + +- [Grubsky Grigory brought this change] + + win32: provide a uint8_t typedef for better building on windows + +- agent: win32: fix bad _libssh2_store_str call + + As pointed out by Grubsky Grigory , I + made a mistake when I added the _libssh2_store_str() call before + and I made a slightly different patch than what he suggested. + Based purely on taste. + +Peter Stuge (24 May 2010) +- [Joey Degges brought this change] + + Add libssh2_sftp_statvfs() and libssh2_sftp_fstatvfs() + + These can be used to get file system statistics from servers that + support the statvfs@openssh.com and fstatvfs@openssh.com extensions. + +Alexander Lamaison (22 May 2010) +- [Jose Baars brought this change] + + VMS specific: make sure final release can be installed over daily build + +- [Jose Baars brought this change] + + VMS: small improvement to the man2help utilities + +Peter Stuge (22 May 2010) +- [Joey Degges brought this change] + + libssh2_exit and libssh2_sftp_readdir man page fixes + +Daniel Stenberg (21 May 2010) +- spelling: s/sue/use + +Alexander Lamaison (21 May 2010) +- Change magic port number for generic knownhost check. + + libssh2_knownhost_checkp took 0 as a magic port number that indicated + a 'generic' check should be performed. However, 0 is a valid port + number in its own right so this commit changes the magic value to any + negative int. + +Mikhail Gusarov (5 May 2010) +- Add re-discovered copyright holders to COPYING + +- Restoring copyright statements from pre-git era + + Eli Fant has contributed fragmenting SFTP requests + +- Restoring my copyright statements from pre-git era + + keyboard_interactive, 'exit-status' information packet, non-atomic read/write + under FreeBSD, multi-channel operation bugfixes. + +Daniel Stenberg (3 May 2010) +- pedantic: make the code C90 clean + +Peter Stuge (3 May 2010) +- Do proper keyboard-interactive user dialog in the sftp.c example + +Daniel Stenberg (3 May 2010) +- added to tarball: libssh2_knownhost_checkp.3 + +- knownhost: support [host]:port in knownhost file + + OpenSSH has ways to add hosts to the knownhosts file that include + a specific port number which makes the key associated with only + that specific host+port pair. libssh2 previously did not support + this, and I was forced to add a new function to the API to + properly expose this ability to applications: + libssh2_knownhost_checkp() + + To *add* such hosts to the knownhosts file, you make sure to pass + on the host name in that manner to the libssh2_knownhost_addc() + function. + +- init/exit: mention these were added in 1.2.5 + +- libssh2_knownhost_check docs: correct the prototype + +- examples: avoid use of uninitialized variable 'sock' + +- KEX: stop pretending we negotiate language + + There was some stub-like parts of an implementation for + implementing kex language negotiation that caused clang-analyzer + to warn and as it did nothing I've now removed the dead code. + +- Uninitialized argument + +- sftpdir: removed dead assignment + +- Makefile.am: include the VMS-specific config header as well + +- [Jose Baars brought this change] + + Add VMS specific libssh2_config.h + +- fix Value stored to 's' is never read warning + + and moved variable declaration of s to be more local + +- kexinit: simplify the code and avoid scan-build warning + + Previously it would say "Value stored to 's' is never read" due + fourth increment of 's'. + +Alexander Lamaison (28 Apr 2010) +- Removed unecessary brackets. + +- Changed sftp_attrsize macro to a static function. + +Daniel Stenberg (28 Apr 2010) +- release: include the VMS-specific files + +- sftp_attrsize: protect the macro argument with proper parentheses + +- ssh2_agent: avoid using 'session' uninitialized on failures + +- examples: remove assignments of variable rc that's never used + +- publickey_init: remove useless variable increment + +- hostkey_method_ssh_rsa_init: remove useless variable increment + +- packet_x11_open: removed useless variable increment + + and made the declaration of a variable more local + +- packet_queue_listener: removed useless variable increment + + and made the declaration of a variable more local + +- sftp_read: move a read_responses array to where its used + + I find that this increases readability since the array is used + only in the function call just immediately below and nowhere + else. + +- sftp_readdir: turn a small array static const and move it + +- sftp_attrsize: converted function to a macro + + This way, the macro can evaluate a static number at compile time + for two out of four uses, and it probably runs faster for the + other two cases too. + +- sftp_open: deal with short channel_write calls + + This was an old TODO that just wasn't done before. If + channel_write returns short, that is not an error. + +- sftp_open: clean up, better check of input data + + The clang-analyzer report made it look into this function and + I've went through it to remove a potential use of an + uninitialized variable and I also added some validation of input + data received from the server. + + In general, lots of more code in this file need to validate the + input before assuming it is correct: there are servers out there + that have bugs or just have another idea of how to do the SFTP + protocol. + +- bugfix: avoid using the socket if it failed to create one + +- bugfix: potential use of NULL pointer + +- libssh2_userauth_password_ex: clarify errors somewhat + + The errors mentioned in this man page are possible return codes + but not necessarily the only return codes that this can return. + + Also reformatted the typ prototypes somewhat. + +- examples: fixed and made them more similar + + The channel read/write functions can return 0 in legitimate cases + without it being an error, and we need to loop properly if they + return short. + +- [Jose Baars brought this change] + + VMS port of libssh2; changes in the libssh2 common code + +- Makefile: added the two news headers userauth.h and session.h + +- cleanup: prefer the internal functions + + To get the blocking vs non-blocking to work as smooth as possible + and behave better internally, we avoid using the external + interfaces when calling functions internally. + + Renamed a few internal functions to use _libssh2 prefix when not + being private within a file, and removed the libssh2_ for one + that was private within the file. + +- session_free: remove dead code + +- libssh2_publickey_init: fixed to work better non-blocking + + This was triggered by a clang-analyzer complaint that turned out + to be valid, and it made me dig deeper and fix some generic non- + blocking problems I disovered in the code. + + While cleaning this up, I moved session-specific stuff over to a + new session.h header from the libssh2_priv.h header. + +- channel: reduce duplicated free and returns + + Simplified the code by trying to free data and return on a single + spot. + +- channel: make variables more local + + By making 'data' and 'data_len' more local in several places in + this file it will be easier to spot how they are used and we'll + get less risks to accidentally do bad things with them. + +Mikhail Gusarov (24 Apr 2010) +- Fix typos in manpages, catched by Lintian + +Daniel Stenberg (24 Apr 2010) +- channel_request_pty: simplify the code + + clang-analyzer pointed out how 'data' could be accessed as a NULL + pointer if the wrong state was set, and while I don't see that + happen in real-life the code flow is easier to read and follow by + moving the LIBSSH2_FREE() call into the block that is supposed to + deal with the data pointer anyway. + +- libssh2_channel_process_startup: simplify the code + + clang-analyzer pointed out how 'data' could be accessed as a NULL + pointer if the wrong state was set, and while I don't see that + happen in real-life the code flow is easier to read and follow by + moving the LIBSSH2_FREE() call into the block that is supposed to + deal with the data pointer anyway. + +- sftp_close_handle: add precation to not access NULL pointer + + clang-analyzer pointed this out as a "Pass-by-value argument in + function call is undefined" but while I can't see exactly how + this can ever happen in reality I think a little check for safety + isn't such a bad thing here. + +- scp_write_nonblock: Value stored to 'nread' is never read + +- scp_write: Value stored to 'ptr' is never read + +- scp_write_nonblock: Value stored to 'ptr' is never read + +- sftp_mkdir: less silly output but show failures + +- [Jose Baars brought this change] + + VMS port of libssh2 including VMS specific build procedures + +- two variable types changes, made lines less than 80 columns + + The two variable type changes are only to match type variable + fields actually read from the binary protocol. + +- remove check for negative padding_length + + It was silly, since it is read as an unsigned char... + +- hostkey_method_ssh_dss_init: Value stored to 's' is never read + +- libssh2_banner_set: avoid unnecessary increment and explain code + +- agent_transact_unix: remove unused variable + +- remove two unnecessary increments + +- more code converted to use _libssh2_store_*() + +- libssh2_publickey_list_fetch: removed unused variables + +- libssh2_publickey_init: remove unused variables + +- libssh2_scp_send64: added to API to provide large file transfers + + The previously existing libssh2_scp_send_ex() function has no way + to send files that are larger than 'size_t' which on 32bit + systems mean 4GB. This new API uses a libssh2_int64_t type and + should thus on most modern systems be able to send enormous + files. + +- sftp_init: remove unused variables and assignments + +- libssh2_knownhost_check: Value stored to 'keylen' is never read + +- hostkey: fix compiler warning + +- remove unused variable + +- data types: convert more to use size_t and uint32_t + +- channel: variable type cleanups + +- cleanups: better binary packet gen, size_t fixes and PACKET_* removal + + I'll introduce a new internal function set named + + _libssh2_store_u32 + _libssh2_store_u64 + _libssh2_store_str + + That can be used all through the library to build binary outgoing + packets. Using these instead of the current approach removes + hundreds of lines from the library while at the same time greatly + enhances readability. I've not yet fully converted everything to + use these functions. + + I've converted LOTS of 'unsigned long' to 'size_t' where + data/string lengths are dealt with internally. This is The Right + Thing and it will help us make the transition to our + size_t-polished API later on as well. + + I'm removing the PACKET_* error codes. They were originally + introduced as a set of separate error codes from the transport + layer, but having its own set of errors turned out to be very + awkward and they were then converted into a set of #defines that + simply maps them to the global libssh2 error codes instead. Now, + I'l take the next logical step and simply replace the PACKET_* + defines with the actual LIBSSH2_ERROR_* defines. It will increase + readability and decrease confusion. + + I also separated packet stuff into its own packet.h header file. + +- clarified the return code + +- rename libssh2_error to the correct _libssh2_error + + We reserve ^libssh2_ for public symbols and we use _libssh2 as + prefix for internal ones. I fixed the intendation of all these + edits with emacs afterwards, which then changed it slightly more + than just _libssh2_error() expressions but I didn't see any + obvious problems. + +- data type cleanup: made lots of code use size_t etc + + A lot of code used 'unsigned long' and the likes when it should + rather just use plain 'int' or use size_t for data lengths. + +- wait_socket: make c89 compliant and use two fd_sets for select() + +- sftp_readdir: always zero terminate, detail the return code + + I also added a description for the 'longentry' field which was + previously undocumented! + +- sftp_readdir: simplified and bugfixed + + This function no longer has any special purpose code for the + single entry case, as it was pointless. + + The previous code would overflow the buffers with an off-by-one + in case the file name or longentry data fields received from the + server were exactly as long as the buffer provided to + libssh2_sftp_readdir_ex. + + We now make sure that libssh2_sftp_readdir_ex() ALWAYS zero + terminate the buffers it fills in. + + The function no longer calls the libssh2_* function again, but + properly uses the internal sftp_* instead. + +- channel/transport: we now drain the outgoing send buffer when we ignore EAGAIN + + When we ignore the EAGAIN from the transport layer within channel_write, we + now drain the outgoing transport layer buffer so that remainders in that + won't cause any problems in the next invoke of _libssh2_transport_write() + +- channel_write: if data has been sent, don't return EAGAIN + + When sending data in a loop, we must not return EAGAIN if we + managed to send data in an earlier round. This was reported in + bug #126 => http://libssh2.stuge.se/ticket/126 + +Simon Josefsson (14 Apr 2010) +- Fix OpenSSL AES-128-CTR detection. + + Patch from Paul Howarth . + +Daniel Stenberg (13 Apr 2010) +- version in header file now says 1.2.6-DEV + +- 1.2.6: clean the RELEASE-NOTES for next release round + +- NEWS: add the stuff from the version 1.2.5 RELEASE-NOTES + +Version 1.2.5 (13 Apr 2010) + +Daniel Stenberg (13 Apr 2010) +- channel_close: no longer wait for the SSH_MSG_CHANNEL_CLOSE message + + As the packet may simply not arrive we cannot have the close + function wait for it unconditionally. + +- less code duplication in the poll vs select code flows + + libssh2_keepalive_send and libssh2_session_block_directions are + now used outside of the #ifdef blocks. + +- make it C90 compliant + +- updated with all changes and bugs since 1.2.4 + +- Added LIBSSH2_SFTP_S_IS***() macros and updated docs + + libssh2_sftp_fstat_ex.3 is now extended quite a lot to describe a + lot of the struct and the bits it uses and how to test for them. + +- sftp_init() deal with _libssh2_channel_write() returns short + + When _libssh2_channel_write() is asked to send off 9 bytes, the + code needs to deal with the situation where less than 9 bytes + were sent off and prepare to send the remaining piece at a later + time. + +- handle a NULL password as if it was "" + + libssh2_userauth_publickey_fromfile_ex() takes a "passphrase" + but didn't deal with it being set to NULL. + +- Reduce used window sizes by factor 10 + + As reported in bug report #166 http://libssh2.stuge.se/ticket/166 + by 'ptjm', the maximum window size must be less crazy for libssh2 + to do better with more server implementations. I did not do any + testing to see how this changes raw SCP performance, but the + maximum window size is still almost 4MB. This also has the upside + that libssh2 will use less memory. + +Peter Stuge (28 Mar 2010) +- Correctly clear blocking flag after sending multipart packet + + commit 7317edab61d2179febc38a2c2c4da0b951d74cbc cleared the outbound + blocking bit when send_existing() returned PACKET_NONE and *ret=0, as + opposed to before even calling send_existing(), but because *ret=1 when + sending parts 2..n of an existing packet, the bit would only be cleared + when calling libssh2_transport_write() for a new packet. + + Clear the direction flag after the final part of a packet has been sent. + +Daniel Stenberg (24 Mar 2010) +- Added man page for libssh2_knownhost_addc() + + Added mention in libssh2_knownhost_add() docs that + libssh2_knownhost_addc() is the preferred function now. + +- at next soname bump remove libssh2_knownhost_add() + +- ignore TAGS ("make tags" makes them) + +- fix memory leak + + we must not assign the pointer a NULL since it keeps allocated + data and at least parts of an error string + +- fixed the pattern for avoiding the poll check + + added some comments about known problems with poll on darwin + +- avoid checking for poll on some systems + + darwin and interix are known to have broken poll implementations + so we skip the check on those and thus have them use select + unconditionally + +- ignore libssh2.dsp + +Simon Josefsson (23 Mar 2010) +- Fix logic in "on-the-fly" crypto init. + +- Make sure keepalive is working even when poll is used. + +- [Paul Querna brought this change] + + Use poll when available on blocking API. + + Signed-off-by: Simon Josefsson + +Peter Stuge (20 Mar 2010) +- Fix speling + +Daniel Stenberg (19 Mar 2010) +- fix NULL dereference when window adjusting a non-existing channel + + Suyog Jadhav pointed out that when receiving a window adjust to + a channel not found, the code would reference a NULL pointer. + Now it will instead output a message about that fact. + +Simon Josefsson (19 Mar 2010) +- Fix build problem. + +- Eat our own dog food, call libssh2_init and libssh2_exit in the examples. + +- Fix init/exit logic. Add self-test of it. + +Daniel Stenberg (19 Mar 2010) +- fix typo + +Simon Josefsson (19 Mar 2010) +- Add man page for libssh2_init and libssh2_exit. Fix libssh2_exit prototype. + +- Shorten constant a bit. More documentation. + +- Fix namespace pollution. + +- Add global init/exit points, to do crypto initialization in one place. + + By Lars Nordin. + +Daniel Stenberg (14 Mar 2010) +- libssh2 is released under the Modifed BSD license, not GPL + +Alexander Lamaison (14 Mar 2010) +- Add libssh2_knownhost_addc to handle comments. + + Comments in known_hosts file were not handle properly. They were parsed as + part of the key causing key matching to return a mismatch if the entry had a + comment. This adds a new API function that takes an optional comment and + changes libssh2_knownhost_readline to parse the comment as pass it to the + new function. + + Fixes #164. + +- Fix gettimeofday to compile with Visual C++ 6. + + Reported by Steven Van Ingelgem. + +Simon Josefsson (10 Mar 2010) +- Add. + +- keepalive.c: Fix libssh2_error usage. + +- Fix typo in last commit. + +- Tidy up build option notice. + +- Add entry about keep alive stuff. + +- Add keep-alive support. + +Alexander Lamaison (7 Mar 2010) +- Untabify. + +- Fix memory leak in libssh2_knownhost_add. + +Daniel Stenberg (6 Mar 2010) +- change 'int' to 'libssh2_socket_t' in the public API for sockets + +- reduce code duplication and return underlying error better + +- acknowledge when _libssh2_packet_requirev() returns error + + when _libssh2_packet_requirev() returns an error when waiting for + SSH_MSG_USERAUTH_SUCCESS or SSH_MSG_USERAUTH_FAILURE, it is an + error and it should be treated as such + +- wrap long lines + +- polished the phrasing in two error strings + +- silence picky compiler warnings + +- silence picky compiler warnings + +- removed libssh2_error()'s forth argument + + libssh2_error() no longer allocates a string and only accepts a const + error string. I also made a lot of functions use the construct of + return libssh2_error(...) instead of having one call to + libssh2_error() and then a separate return call. In several of those + cases I then also changed the former -1 return code to a more + detailed one - something that I think will not change behaviors + anywhere but it's worth keeping an eye open for any such. + +- repaired --enable-debug + +Simon Josefsson (1 Mar 2010) +- Make ./configure output a summary of build options. + +Daniel Stenberg (1 Mar 2010) +- let the err_msg in the session struct be const too + +Simon Josefsson (1 Mar 2010) +- Revert #ifdef change that pulled in AES-CTR code when explicitly disabled. + +Daniel Stenberg (1 Mar 2010) +- fix #ifdefs + +- make function match the new proto + +Simon Josefsson (1 Mar 2010) +- Improve AES-CTR check. + +Daniel Stenberg (1 Mar 2010) +- use const to silence a bazillion warnings + +Simon Josefsson (1 Mar 2010) +- Use AES-CTR from OpenSSL when available. + + Reported by Lars Nordin . + +- Make it possible to disable DSA. + + Patch from Lars Nordin . + +Peter Stuge (1 Mar 2010) +- Send and receive channel EOF before sending SSH_MSG_CHANNEL_CLOSE + + Sending SSH_MSG_CHANNEL_CLOSE without channel EOF is explicitly allowed + in RFC 4254, but some non-conforming servers will hang or time out when + the channel is closed before EOF. + + Other common clients send and receive EOF before closing, there are no + drawbacks, and some servers need it to work correctly. + +Alexander Lamaison (26 Feb 2010) +- Style improvements to knownhost error handling. + + Made improvements as suggested by Peter Stuge: http://www.libssh2.org/mail/libssh2-devel-archive-2010-02/0161.shtml. + +- Call libssh2_error for every knownhost API failure. + + The libssh2 API calls should set the last error code and a message when + returning a failure by calling libssh2_error. This changeset adds these + calls to the libssh2_knownhost_* API as well as libssh2_base64_decode. + + This change also makes libssh2_error into a function rather than a macro. + Its implementation is moved to misc.c. This function returns the error + code passed to it allowing callers to return the error value directly + without duplicating the error code. + +- Fix LIBSSH2_ALLOC checks. + + These appear to be cut-and paste errors where the wrong variable is checked + for NULLness after calling LIBSSH2_ALLOC. + +Simon Josefsson (23 Feb 2010) +- Silence compiler warning. + +- Make it portable; test uses = for string comparison (not ==). Indent. + +Alexander Lamaison (22 Feb 2010) +- libssh2_knownhost_del: fix write to freed memory. + + When removing a known host, libssh2_knownhost_del would remove the node from the linked list, free its memory and then overwrite the struct parameter (which indicated which node to remove) with 0. However, this struct is actually allocated within the just-freed node meaning we're writing to freed memory. This made Windows very upset. + + The fix is simply to overwrite the struct first before freeing the memory. + +Daniel Stenberg (21 Feb 2010) +- show more verbose error when SCP send fails + +- libssh2_socket_t is done, a library-free function is needed + +- clarify that this frees all data associated with a session + +- improved error handling + +- add missing libssh2_error() calls + + To make sure the public API is functional and that the + BLOCK_ADJUST_ERRNO() macro works correctly we MUST make sure to + call libssh2_error() when we return errors. + +- fix memory leak in userauth_keyboard_interactive() + + Mr anonymous in bug #125 pointed out that the userauth_keyboard_interactive() + function does in fact assign the same pointer a second time to a new allocated + buffer without properly freeing the previous one, which caused a memory leak. + +- added missing error codes + + To allow the libssh2_session_last_error() function to work as + documented, userauth_password() now better makes sure to call + libssh2_error() everywhere before it returns error. + + Pointed out by mr anonymous in bug #128 + +Peter Stuge (16 Feb 2010) +- Fix resource and memory leaks in examples as reported by cppcheck + + Thanks to Ettl Martin for the report and patch. This fixes #132 + +Daniel Stenberg (15 Feb 2010) +- mention the new man pages for macros + +- added man pages for API macros + + all #defined macros in the public headers are considered to be part + of the API and I've generated individual man pages for each of them + to A) make it easier to figure out what each function/macro actually + is for so that automated lookups work better and for B) make sure we + have all public functions document (both macros and functions) to + make it easier for us to work away from all the macros in a future + release. + +- Committed the patch by Yoichi Iwaki in bug #2929647 + + Committed the patch by Yoichi Iwaki in bug #2929647, which fixed a memory + leak when an 'outbuf' was still allocated when a session was freed. + +- free "outbuf" when killing a session + + Fix memoary leak: if there was an "output" still allocated when a + session was torn down it needs to be freed in session_free() + + Patch by Yoichi Iwaki in bug #2929647 + +- the working version name is now 1.2.5_DEV + +Version 1.2.4 (13 Feb 2010) + +Daniel Stenberg (13 Feb 2010) +- updated info for 1.2.4 + +Dan Fandrich (10 Feb 2010) +- Allow compiling with OpenSSL when AES isn't available. + +Peter Stuge (9 Feb 2010) +- [Dave McCaldon brought this change] + + Fix Tru64 socklen_t compile issue with example/direct_tcpip.c + + Building libssh2-1.2.3 on Tru64 fails at line 48 and 166 because socklen_t + isn't defined on Tru64 unless _POSIX_PII_SOCKET is defined. + + This patch updates configure.ac to add -D_POSIX_PII_SOCKET when building + on Tru64 platform(s). + +- [Dave McCaldon brought this change] + + Resolve compile issues on Solaris x64 and UltraSPARC + + Solaris builds of libssh2-1.2.3 failed on both x64 and UltraSPARC + platforms because of two problems: + + 1) src/agent.c:145 sun is a reserved word when using the SUNWspro compiler + 2) example/direct_tcpip.c:84 INADDR_NONE is not defined + +Daniel Stenberg (3 Feb 2010) +- towards 1.2.4 now + +Version 1.2.3 (3 Feb 2010) + +Daniel Stenberg (3 Feb 2010) +- Version 1.2.3 (February 3, 2010) + +- fix building out of source tree by proving better include path + + when building out of source tree, we provide -I$(top_builddir)/example + since the libssh2_config.h gets generated in that dir + +Peter Stuge (1 Feb 2010) +- [Sofian Brabez brought this change] + + Replace : in hexdump with " " (two spaces) + +- Detect when the forwarded connection is closed in example/direct_tcpip.c + +- Fix example/direct_tcpip.c to work also on WIN32 + + read() and write() are no good for WIN32 sockets, use recv() and send(). + +- Ignore libssh2_config.h.in and stamp-h2 in example/ and remove .cvsignore + +- Simplify WIN32 ifdefs in example/direct_tcpip.c to allow standalone compile + +- Always #define INVALID_SOCKET -1 in libssh2_priv.h when not on win32 + + Fix broken builds since commit abd9bd0bbe631efeada1f54552c70b54e1c490c1 + for all non-win32 platforms. + +- Include hmac-md5 and hmac-md5-96 only if crypto backend supports MD5 + +- Use LIBSSH2_HOSTKEY_HASH_SHA1 instead of _MD5 in examples and tests + + MD5 support is optional and may not always be available, while SHA1 is both + required and recommended. + +- Update mailing list address in configure.ac to @cool.haxx.se + +- Make example/direct_tcpip.c compile for win32 + + One warning from FD_SET() remains, it is also in some other examples. + +- Correctly check for an invalid socket in session_startup() + +- Small documentation fix after Dave's _USERAUTH_FAILURE improvement + +- [Dave McCaldon brought this change] + + Handle SSH_MSG_USERAUTH_FAILURE for password and kbd-int authentication + + Neither libssh2_userauth_password_ex() nor + libssh2_userauth_keyboard_interactive_ex() would return a login failure + error if the server responded with a SSH_MSG_USERAUTH_FAILURE, instead + you would see whatever previous error had occurred, typically + LIBSSH2_ERROR_EAGAIN. + + This patch changes error code -18 to LIBSSH2_ERROR_AUTHENTICATION_FAILED + and makes LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED an alias for + LIBSSH2_ERROR_AUTHENTICATION_FAILED. In addition, new logic in + userauth_password() properly handles SSH_MSG_USERAUTH_FAILURE and both + this function and userauth_keyboard_interactive() now properly return + LIBSSH2_ERROR_AUTHENTICATION_FAILED. + +Simon Josefsson (28 Jan 2010) +- Fix. + +- Also deal with GLOBAL_REQUEST keep-alives. + +- Make OpenSSH-style keepalive work against libssh2 clients. + +Daniel Stenberg (27 Jan 2010) +- clarified + +Peter Stuge (26 Jan 2010) +- [Dave McCaldon brought this change] + + Fix trace context lookup in libssh2_debug() + + The trace context is actually a bitmask so that tracing output can be + controlled by setting a bitmask using libssh2_trace(). However, the logic + in libssh2_debug() that converted the context to a string was using the + context value as an array index. Because the code used a bounds check on + the array, there was never a danger of a crash, but you would certainly + either get the wrong string, or "unknown". + + This patch adds a lookup that iterates over the context strings and uses + it's index to check for the corresponding bit in the context. + +- Fix typo in RELEASE-NOTES + +Daniel Stenberg (20 Jan 2010) +- updated for 1.2.3 with all the stuff I found in the log + +- ignore more generated files + +- [Dave McCaldon brought this change] + + Pass user context through libssh2_trace_sethandler() to callback + + The libssh2_trace_sethandler() call allows the user to handle the output of libssh2 rather than having it written to stderr. This patch updates libssh2_trace_sethandler() to allow a user-defined void* context value to be passed back to the output handler. + +- [Dave McCaldon brought this change] + + Add libssh2_trace_sethandler() to the API (even more) + +- [Dave McCaldon brought this change] + + Add libssh2_trace_sethandler() to the API + +- cleanup includes + + We now produce a local libssh2_config.h file in this dir for the + examples to use so I cleaned up the include path at the same time. + +- generate a libssh2_config.h in the example dir + + buildconf copies the template to example/ and configure makes sure + to generate a proper file from it and the direct_tcpip.c example + is the first one to use it - to make sure it builds fine on more + paltforms + +Simon Josefsson (13 Jan 2010) +- Remove redundant #includes and reorder sys/types.h include. + +Daniel Stenberg (10 Jan 2010) +- avoid a free(NULL) + +Simon Josefsson (7 Jan 2010) +- Make it simpler to get more debug info. + +Daiki Ueno (1 Jan 2010) +- Simplify the commit 63457dfa using type cast from size_t * to ulong *. + +Alexander Lamaison (30 Dec 2009) +- Fixed memory leak in userauth_publickey(). + + userauth_publickey_fromfile() reads the key from a + file using file_read_publickey() which returns two + allocated strings, the decoded key and the key + method (such as "ssh-dss"). The latter can be + derived from the former but returning both avoids a + later allocation while doing so. + + Older versions of userauth_publickey_fromfile() used + this method string directly but when + userauth_publickey() was factored out of + userauth_publickey_fromfile() it derived the method + from the key itself. This resulted in the method + being allocated twice. + + This fix, which maintains the optimisation that + avoids an extra allocation, changes + userauth_publickey() so it doesn't allocate and + derive the method when userauth_pblc_method already + has a value. + + Signed-off-by: Alexander Lamaison + +Daiki Ueno (25 Dec 2009) +- Fix the return value description of libssh2_knownhost_free(). + +- Fix compiler warnings for size_t pointers on 32-bit Windows. + +- Define INVALID_SOCKET and use it instead of SOCKET_BAD. + + Revert the part of previous commit that defines SOCKET_BAD library wide. + +- Use libssh2_socket_t in the ssh-agent stuff. + Define a portability macro SOCKET_BAD which means "invalid socket". + +- Mark/unmark connection to Pageant is open/close. + +- Add test to check if the socket is connected. + +Peter Stuge (24 Dec 2009) +- Add libssh2.pc to top-level .gitignore + +- Fix publickey authentication regression + + Commit 70b199f47659a74b8778c528beccf893843e5ecb introduced a parsing + bug in file_read_publickey() which made the algorithm name contain an + extra trailing space character, breaking all publickey authentication. + +- Add a direct-tcpip example which shows local port forwarding + +- Add session parameter and LIBSSH2_TRACE_SOCKET to libssh2_trace(3) man page + +- Add TODO: Expose error messages sent by the server + +Daiki Ueno (23 Dec 2009) +- Fix doc comments. + +- Add man pages for ssh-agent API. + +- Don't request userauthlist after authentication. + +Simon Josefsson (21 Dec 2009) +- Add. + +- [Daiki Ueno brought this change] + + Add an example to use ssh-agent API. + + Signed-off-by: Simon Josefsson + +- [Daiki Ueno brought this change] + + Add ssh-agent API. + + Signed-off-by: Simon Josefsson + +- [Daiki Ueno brought this change] + + Add callback-based API for publickey auth. + + Signed-off-by: Simon Josefsson + +- Move examples from example/simple to example/. + +- Move examples from example/simple to example/. + +Daniel Stenberg (17 Dec 2009) +- _libssh2_list_insert() fixed to work + + While this is code not currently in use, it is part of the generic linked + list code and since I found the error I thought I'd better fix it since we + might bring in this function into the code one day. + +Simon Josefsson (16 Dec 2009) +- Silence compiler warnings. + + Based on patch by Kamil Dudka in + . + +- [Kamil Dudka brought this change] + + libgcrypt: simplify code of _libssh2_dsa_sha1_sign + + Signed-off-by: Simon Josefsson + +- [Kamil Dudka brought this change] + + libgcrypt: follow-up for ssh-dss padding fix + + Signed-off-by: Simon Josefsson + +Dan Fandrich (15 Dec 2009) +- Check for the right environment variable in the test app + +Simon Josefsson (14 Dec 2009) +- Silence warning about unused function parameter. + + Reported by Steven Van Ingelgem . + +Daniel Stenberg (10 Dec 2009) +- avoid returning data to memory already freed + + In case of failure we must make sure that the data we return + doesn't point to a memory area already freed. Reported anonymously + in the bug report #2910103. + +Peter Stuge (8 Dec 2009) +- Use LIBSSH2_TRACE_* internally and remove redundant LIBSSH2_DBG_* + +- Add LIBSSH2_TRACE_SOCKET context for tracing send() and recv() + + Helpful in debugging the -39 errors. + +- Another transport layer fix for bogus -39 (LIBSSH2_ERROR_BAD_USE) errors + + Commit 683aa0f6b52fb1014873c961709102b5006372fc made send_existing() send + more than just the second part of a packet when the kernel did not accept + the full packet, but the function still overlooked the SSH protocol + overhead in each packet, often 48 bytes. + + If only the last few bytes of a packet remained, then the packet would + erroneously be considered completely sent, and the next call to write + more data in the session would return a -39 error. + +Daniel Stenberg (6 Dec 2009) +- move local variable to be more localized + +- fixed some indent mistakes + +Peter Stuge (6 Dec 2009) +- Fix padding in ssh-dss signature blob encoding + + DSA signatures consist of two 160-bit integers called r and s. In ssh-dss + signature blobs r and s are stored directly after each other in binary + representation, making up a 320-bit (40 byte) string. (See RFC4253 p14.) + + The crypto wrappers in libssh2 would either pack r and s incorrectly, or + fail, when at least one integer was small enough to be stored in 19 bytes + or less. + + The patch ensures that r and s are always stored as two 160 bit numbers. + +- Don't always clear write direction blocking flag + + When libssh2_transport_write() is called to continue sending a + partially sent packet the write direction flag must not be cleared + until the previous packet has been completely sent, or the app would + hang if the packet still isn't sent completely, since select() gets + called by the internal blocking emulation layer in libssh2 but would + then not be watching the socket for writability. + + Clear the flag only once processing of previous packet data is + complete and a new packet is about to be prepared. + +Alexander Lamaison (24 Nov 2009) +- Detabify. + +- [Daniel Stenberg brought this change] + + Fixed memory leak in sftp_fstat(). + +Simon Josefsson (17 Nov 2009) +- Mark date of 1.2.2 release. + +- Merge branch 'master' of ssh://git.stuge.se/var/lib/git/libssh2 + +Version 1.2.2 (16 Nov 2009) + +Daniel Stenberg (16 Nov 2009) +- prepared for 1.2.2 + +Simon Josefsson (16 Nov 2009) +- Improve NEWS items. + +- Support AES-Counter ciphers. + +- Silence compiler warning. + + Reported by Steven Van Ingelgem + in . + +- Mention libssh2-style.el. + +- Use memmove instead of memcpy on overlapping memory areas. + + Reported by Bob Alexander in + . + +- Add. + +- Protect against crash on too small SSH_MSG_IGNORE packets. + + Reported by Bob Alexander + in . + +- add copyright line diff --git a/libssh2/NMakefile b/libssh2/NMakefile new file mode 100644 index 000000000..07bc2ddad --- /dev/null +++ b/libssh2/NMakefile @@ -0,0 +1,33 @@ +!include "win32/config.mk" + +!if "$(WITH_WINCNG)" == "1" +!include "Makefile.WinCNG.inc" +!else +!include "Makefile.OpenSSL.inc" +!endif +!include "Makefile.inc" + +OBJECTS=$(CSOURCES:.c=.obj) + +# SUBDIRS=src example +SUBDIRS=src + +all-sub: win32\objects.mk + -for %D in ($(SUBDIRS)) do $(MAKE) /nologo /f %D/NMakefile BUILD=$(BUILD) SUBDIR=%D all-sub + +clean: + -rmdir 2>NUL /s/q $(TARGET) + -del 2>NUL win32\objects.mk + +real-clean vclean: clean + -del 2>NUL libssh2.dll + -del 2>NUL libssh2.exp + -del 2>NUL libssh2.ilk + -del 2>NUL libssh2.lib + -del 2>NUL *.pdb + +win32\objects.mk: Makefile.inc + @echo OBJECTS = \>$@ + @for %O in ($(OBJECTS)) do @echo $$(INTDIR)\%O \>>$@ + @echo $$(EOL)>>$@ + diff --git a/libssh2/README b/libssh2/README new file mode 100644 index 000000000..8a148568c --- /dev/null +++ b/libssh2/README @@ -0,0 +1,19 @@ +libssh2 - SSH2 library +====================== + +libssh2 is a library implementing the SSH2 protocol, available under +the revised BSD license. + +Web site: https://www.libssh2.org/ + +Mailing list: https://cool.haxx.se/mailman/listinfo/libssh2-devel + +License: see COPYING + +Source code: https://github.com/libssh2/libssh2 + +Web site source code: https://github.com/libssh2/www + +Installation instructions are in: + - docs/INSTALL_CMAKE for CMake + - docs/INSTALL_AUTOTOOLS for Autotools diff --git a/libssh2/RELEASE-NOTES b/libssh2/RELEASE-NOTES new file mode 100644 index 000000000..5b78ede38 --- /dev/null +++ b/libssh2/RELEASE-NOTES @@ -0,0 +1,31 @@ +libssh2 1.8.0 + +This release includes the following changes: + + o added a basic dockerised test suite + o crypto: add support for the mbedTLS backend + +This release includes the following bugfixes: + + o libgcrypt: fixed a NULL pointer dereference on OOM + o VMS: can't use %zd for off_t format + o VMS: update vms/libssh2_config.h + o windows: link with crypt32.lib + o libssh2_channel_open: speeling error fixed in channel error message + o msvc: fixed 14 compilation warnings + o tests: HAVE_NETINET_IN_H was not defined correctly + o openssl: add OpenSSL 1.1.0 compatibility + o cmake: Add CLEAR_MEMORY option, analogously to that for autoconf + o configure: make the --with-* options override the OpenSSL default + o libssh2_wait_socket: set err_msg on errors + o libssh2_wait_socket: Fix comparison with api_timeout to use milliseconds + +This release would not have looked like this without help, code, reports and +advice from friends like these: + + Alexander Lamaison, Antenore Gatta, Brad Harder, Charles Collicutt, + Craig A. Berry, Dan Fandrich, Daniel Stenberg, Kamil Dudka, Keno Fischer, + Taylor Holberton, Viktor Szakats, Will Cosgrove, Zenju + (12 contributors) + + Thanks! (and sorry if I forgot to mention someone) diff --git a/libssh2/acinclude.m4 b/libssh2/acinclude.m4 new file mode 100644 index 000000000..734ef070c --- /dev/null +++ b/libssh2/acinclude.m4 @@ -0,0 +1,467 @@ + +dnl ********************************************************************** +dnl CURL_DETECT_ICC ([ACTION-IF-YES]) +dnl +dnl check if this is the Intel ICC compiler, and if so run the ACTION-IF-YES +dnl sets the $ICC variable to "yes" or "no" +dnl ********************************************************************** +AC_DEFUN([CURL_DETECT_ICC], +[ + ICC="no" + AC_MSG_CHECKING([for icc in use]) + if test "$GCC" = "yes"; then + dnl check if this is icc acting as gcc in disguise + AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER], + dnl action if the text is found, this it has not been replaced by the + dnl cpp + ICC="no", + dnl the text was not found, it was replaced by the cpp + ICC="yes" + AC_MSG_RESULT([yes]) + [$1] + ) + fi + if test "$ICC" = "no"; then + # this is not ICC + AC_MSG_RESULT([no]) + fi +]) + +dnl We create a function for detecting which compiler we use and then set as +dnl pendantic compiler options as possible for that particular compiler. The +dnl options are only used for debug-builds. + +AC_DEFUN([CURL_CC_DEBUG_OPTS], +[ + if test "z$ICC" = "z"; then + CURL_DETECT_ICC + fi + + if test "$GCC" = "yes"; then + + dnl figure out gcc version! + AC_MSG_CHECKING([gcc version]) + gccver=`$CC -dumpversion` + num1=`echo $gccver | cut -d . -f1` + num2=`echo $gccver | cut -d . -f2` + gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null` + AC_MSG_RESULT($gccver) + + if test "$ICC" = "yes"; then + dnl this is icc, not gcc. + + dnl ICC warnings we ignore: + dnl * 269 warns on our "%Od" printf formatters for curl_off_t output: + dnl "invalid format string conversion" + dnl * 279 warns on static conditions in while expressions + dnl * 981 warns on "operands are evaluated in unspecified order" + dnl * 1418 "external definition with no prior declaration" + dnl * 1419 warns on "external declaration in primary source file" + dnl which we know and do on purpose. + + WARN="-wd279,269,981,1418,1419" + + if test "$gccnum" -gt "600"; then + dnl icc 6.0 and older doesn't have the -Wall flag + WARN="-Wall $WARN" + fi + else dnl $ICC = yes + dnl this is a set of options we believe *ALL* gcc versions support: + WARN="-W -Wall -Wwrite-strings -pedantic -Wpointer-arith -Wnested-externs -Winline -Wmissing-prototypes" + + dnl -Wcast-align is a bit too annoying on all gcc versions ;-) + + if test "$gccnum" -ge "207"; then + dnl gcc 2.7 or later + WARN="$WARN -Wmissing-declarations" + fi + + if test "$gccnum" -gt "295"; then + dnl only if the compiler is newer than 2.95 since we got lots of + dnl "`_POSIX_C_SOURCE' is not defined" in system headers with + dnl gcc 2.95.4 on FreeBSD 4.9! + WARN="$WARN -Wundef -Wno-long-long -Wsign-compare" + fi + + if test "$gccnum" -ge "296"; then + dnl gcc 2.96 or later + WARN="$WARN -Wfloat-equal" + fi + + if test "$gccnum" -gt "296"; then + dnl this option does not exist in 2.96 + WARN="$WARN -Wno-format-nonliteral" + fi + + dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on + dnl on i686-Linux as it gives us heaps with false positives. + dnl Also, on gcc 4.0.X it is totally unbearable and complains all + dnl over making it unusable for generic purposes. Let's not use it. + + if test "$gccnum" -ge "303"; then + dnl gcc 3.3 and later + WARN="$WARN -Wendif-labels -Wstrict-prototypes" + fi + + if test "$gccnum" -ge "304"; then + # try these on gcc 3.4 + WARN="$WARN -Wdeclaration-after-statement" + fi + + for flag in $CPPFLAGS; do + case "$flag" in + -I*) + dnl Include path, provide a -isystem option for the same dir + dnl to prevent warnings in those dirs. The -isystem was not very + dnl reliable on earlier gcc versions. + add=`echo $flag | sed 's/^-I/-isystem /g'` + WARN="$WARN $add" + ;; + esac + done + + fi dnl $ICC = no + + CFLAGS="$CFLAGS $WARN" + + AC_MSG_NOTICE([Added this set of compiler options: $WARN]) + + else dnl $GCC = yes + + AC_MSG_NOTICE([Added no extra compiler options]) + + fi dnl $GCC = yes + + dnl strip off optimizer flags + NEWFLAGS="" + for flag in $CFLAGS; do + case "$flag" in + -O*) + dnl echo "cut off $flag" + ;; + *) + NEWFLAGS="$NEWFLAGS $flag" + ;; + esac + done + CFLAGS=$NEWFLAGS + +]) dnl end of AC_DEFUN() + +dnl CURL_CHECK_NONBLOCKING_SOCKET +dnl ------------------------------------------------- +dnl Check for how to set a socket to non-blocking state. There seems to exist +dnl four known different ways, with the one used almost everywhere being POSIX +dnl and XPG3, while the other different ways for different systems (old BSD, +dnl Windows and Amiga). +dnl +dnl There are two known platforms (AIX 3.x and SunOS 4.1.x) where the +dnl O_NONBLOCK define is found but does not work. This condition is attempted +dnl to get caught in this script by using an excessive number of #ifdefs... +dnl +AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET], +[ + AC_MSG_CHECKING([non-blocking sockets style]) + + AC_TRY_COMPILE([ +/* headers for O_NONBLOCK test */ +#include +#include +#include +],[ +/* try to compile O_NONBLOCK */ + +#if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# if defined(__SVR4) || defined(__srv4__) +# define PLATFORM_SOLARIS +# else +# define PLATFORM_SUNOS4 +# endif +#endif +#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41) +# define PLATFORM_AIX_V3 +#endif + +#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__) +#error "O_NONBLOCK does not work on this platform" +#endif + int socket; + int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK); +],[ +dnl the O_NONBLOCK test was fine +nonblock="O_NONBLOCK" +AC_DEFINE(HAVE_O_NONBLOCK, 1, [use O_NONBLOCK for non-blocking sockets]) +],[ +dnl the code was bad, try a different program now, test 2 + + AC_TRY_COMPILE([ +/* headers for FIONBIO test */ +#include +#include +],[ +/* FIONBIO source test (old-style unix) */ + int socket; + int flags = ioctl(socket, FIONBIO, &flags); +],[ +dnl FIONBIO test was good +nonblock="FIONBIO" +AC_DEFINE(HAVE_FIONBIO, 1, [use FIONBIO for non-blocking sockets]) +],[ +dnl FIONBIO test was also bad +dnl the code was bad, try a different program now, test 3 + + AC_TRY_COMPILE([ +/* headers for ioctlsocket test (Windows) */ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#endif +],[ +/* ioctlsocket source code */ + SOCKET sd; + unsigned long flags = 0; + sd = socket(0, 0, 0); + ioctlsocket(sd, FIONBIO, &flags); +],[ +dnl ioctlsocket test was good +nonblock="ioctlsocket" +AC_DEFINE(HAVE_IOCTLSOCKET, 1, [use ioctlsocket() for non-blocking sockets]) +],[ +dnl ioctlsocket didnt compile!, go to test 4 + + AC_TRY_LINK([ +/* headers for IoctlSocket test (Amiga?) */ +#include +],[ +/* IoctlSocket source code */ + int socket; + int flags = IoctlSocket(socket, FIONBIO, (long)1); +],[ +dnl ioctlsocket test was good +nonblock="IoctlSocket" +AC_DEFINE(HAVE_IOCTLSOCKET_CASE, 1, [use Ioctlsocket() for non-blocking sockets]) +],[ +dnl Ioctlsocket didnt compile, do test 5! + AC_TRY_COMPILE([ +/* headers for SO_NONBLOCK test (BeOS) */ +#include +],[ +/* SO_NONBLOCK source code */ + long b = 1; + int socket; + int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); +],[ +dnl the SO_NONBLOCK test was good +nonblock="SO_NONBLOCK" +AC_DEFINE(HAVE_SO_NONBLOCK, 1, [use SO_NONBLOCK for non-blocking sockets]) +],[ +dnl test 5 didnt compile! +nonblock="nada" +AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1, [disabled non-blocking sockets]) +]) +dnl end of fifth test + +]) +dnl end of forth test + +]) +dnl end of third test + +]) +dnl end of second test + +]) +dnl end of non-blocking try-compile test + AC_MSG_RESULT($nonblock) + + if test "$nonblock" = "nada"; then + AC_MSG_WARN([non-block sockets disabled]) + fi +]) + +dnl CURL_CHECK_NEED_REENTRANT_SYSTEM +dnl ------------------------------------------------- +dnl Checks if the preprocessor _REENTRANT definition +dnl must be unconditionally done for this platform. +dnl Internal macro for CURL_CONFIGURE_REENTRANT. + +AC_DEFUN([CURL_CHECK_NEED_REENTRANT_SYSTEM], [ + case $host in + *-*-solaris* | *-*-hpux*) + tmp_need_reentrant="yes" + ;; + *) + tmp_need_reentrant="no" + ;; + esac +]) + + +dnl CURL_CONFIGURE_FROM_NOW_ON_WITH_REENTRANT +dnl ------------------------------------------------- +dnl This macro ensures that configuration tests done +dnl after this will execute with preprocessor symbol +dnl _REENTRANT defined. This macro also ensures that +dnl the generated config file defines NEED_REENTRANT +dnl and that in turn setup.h will define _REENTRANT. +dnl Internal macro for CURL_CONFIGURE_REENTRANT. + +AC_DEFUN([CURL_CONFIGURE_FROM_NOW_ON_WITH_REENTRANT], [ +AC_DEFINE(NEED_REENTRANT, 1, + [Define to 1 if _REENTRANT preprocessor symbol must be defined.]) +cat >>confdefs.h <<_EOF +#ifndef _REENTRANT +# define _REENTRANT +#endif +_EOF +]) + + +dnl CURL_CONFIGURE_REENTRANT +dnl ------------------------------------------------- +dnl This first checks if the preprocessor _REENTRANT +dnl symbol is already defined. If it isn't currently +dnl defined a set of checks are performed to verify +dnl if its definition is required to make visible to +dnl the compiler a set of *_r functions. Finally, if +dnl _REENTRANT is already defined or needed it takes +dnl care of making adjustments necessary to ensure +dnl that it is defined equally for further configure +dnl tests and generated config file. + +AC_DEFUN([CURL_CONFIGURE_REENTRANT], [ + AC_PREREQ([2.50])dnl + # + AC_MSG_CHECKING([if _REENTRANT is already defined]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + ]],[[ +#ifdef _REENTRANT + int dummy=1; +#else + force compilation error +#endif + ]]) + ],[ + AC_MSG_RESULT([yes]) + tmp_reentrant_initially_defined="yes" + ],[ + AC_MSG_RESULT([no]) + tmp_reentrant_initially_defined="no" + ]) + # + if test "$tmp_reentrant_initially_defined" = "no"; then + AC_MSG_CHECKING([if _REENTRANT is actually needed]) + CURL_CHECK_NEED_REENTRANT_SYSTEM + + if test "$tmp_need_reentrant" = "yes"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi + # + AC_MSG_CHECKING([if _REENTRANT is onwards defined]) + if test "$tmp_reentrant_initially_defined" = "yes" || + test "$tmp_need_reentrant" = "yes"; then + CURL_CONFIGURE_FROM_NOW_ON_WITH_REENTRANT + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + # +]) + +AC_DEFUN([LIBSSH2_CHECKFOR_MBEDTLS], [ + + old_LDFLAGS=$LDFLAGS + old_CFLAGS=$CFLAGS + if test -n "$use_mbedtls" && test "$use_mbedtls" != "no"; then + LDFLAGS="$LDFLAGS -L$use_mbedtls/lib" + CFLAGS="$CFLAGS -I$use_mbedtls/include" + fi + + AC_LIB_HAVE_LINKFLAGS([mbedtls], [], [ + #include + ]) + + if test "$ac_cv_libmbedtls" = "yes"; then + AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use mbedtls]) + LIBSREQUIRED= # mbedtls doesn't provide a .pc file + LIBS="$LIBS -lmbedtls -lmbedcrypto" + found_crypto=libmbedtls + support_clear_memory=yes + else + # restore + LDFLAGS=$old_LDFLAGS + CFLAGS=$old_CFLAGS + fi +]) + +AC_DEFUN([LIBSSH2_CHECKFOR_GCRYPT], [ + + old_LDFLAGS=$LDFLAGS + old_CFLAGS=$CFLAGS + if test -n "$use_libgcrypt" && test "$use_libgcrypt" != "no"; then + LDFLAGS="$LDFLAGS -L$use_libgcrypt/lib" + CFLAGS="$CFLAGS -I$use_libgcrypt/include" + fi + AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [ + #include + ]) + + if test "$ac_cv_libgcrypt" = "yes"; then + AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt]) + LIBSREQUIRED= # libgcrypt doesn't provide a .pc file. sad face. + LIBS="$LIBS -lgcrypt" + found_crypto=libgcrypt + else + # restore + LDFLAGS=$old_LDFLAGS + CFLAGS=$old_CFLAGS + fi +]) + + +AC_DEFUN([LIBSSH2_CHECKFOR_WINCNG], [ + + # Look for Windows Cryptography API: Next Generation + + AC_LIB_HAVE_LINKFLAGS([bcrypt], [], [ + #include + #include + ]) + AC_LIB_HAVE_LINKFLAGS([crypt32], [], [ + #include + #include + ]) + AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [ + #include + ]) + AC_CHECK_DECLS([SecureZeroMemory], [], [], [ + #include + ]) + + if test "$ac_cv_libbcrypt" = "yes"; then + AC_DEFINE(LIBSSH2_WINCNG, 1, [Use Windows CNG]) + LIBSREQUIRED= # wincng doesn't provide a .pc file. sad face. + LIBS="$LIBS -lbcrypt" + if test "$ac_cv_libcrypt32" = "yes"; then + LIBS="$LIBS -lcrypt32" + fi + found_crypto="Windows Cryptography API: Next Generation" + if test "$ac_cv_have_decl_SecureZeroMemory" = "yes"; then + support_clear_memory=yes + fi + fi +]) diff --git a/libssh2/aclocal.m4 b/libssh2/aclocal.m4 new file mode 100644 index 000000000..41ad8c694 --- /dev/null +++ b/libssh2/aclocal.m4 @@ -0,0 +1,1198 @@ +# generated automatically by aclocal 1.15 -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. + +# 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# 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. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# 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. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# 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. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# 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. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# +# 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. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# 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. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# 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. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# 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. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# +# 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. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# +# 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. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/autobuild.m4]) +m4_include([m4/lib-ld.m4]) +m4_include([m4/lib-link.m4]) +m4_include([m4/lib-prefix.m4]) +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) +m4_include([acinclude.m4]) diff --git a/libssh2/buildconf b/libssh2/buildconf new file mode 100644 index 000000000..558dcb660 --- /dev/null +++ b/libssh2/buildconf @@ -0,0 +1,22 @@ +#!/bin/sh + +LIBTOOLIZE="libtoolize" + +if [ "x`which $LIBTOOLIZE`" = "x" ]; then + LIBTOOLIZE="glibtoolize" +fi + +if [ "x`which $LIBTOOLIZE`" = "x" ]; then + echo "Neither libtoolize nor glibtoolize could be found!" + exit 1 +fi + +${LIBTOOLIZE} --copy --automake --force +${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS +${AUTOHEADER:-autoheader} +# copy the private libssh2_config.h.in to the examples dir so that +# it can be included without pointing the include path to the private +# source dir +cp src/libssh2_config.h.in example/libssh2_config.h.in +${AUTOCONF:-autoconf} +${AUTOMAKE:-automake} --add-missing --copy diff --git a/libssh2/cmake/CheckFunctionExistsMayNeedLibrary.cmake b/libssh2/cmake/CheckFunctionExistsMayNeedLibrary.cmake new file mode 100644 index 000000000..8ac61abe5 --- /dev/null +++ b/libssh2/cmake/CheckFunctionExistsMayNeedLibrary.cmake @@ -0,0 +1,81 @@ +# Copyright (c) 2014 Alexander Lamaison +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided +# that the following conditions are met: +# +# Redistributions of source code must retain the above +# copyright notice, this list of conditions and the +# following disclaimer. +# +# 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. +# +# Neither the name of the copyright holder nor the names +# of any other contributors may be used to endorse or +# promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + + +# - check_function_exists_maybe_need_library( [lib1 ... libn]) +# +# Check if function is available for linking, first without extra libraries, and +# then, if not found that way, linking in each optional library as well. This +# function is similar to autotools AC_SEARCH_LIBS. +# +# If the function if found, this will define . +# +# If the function was only found by linking in an additional library, this +# will define NEED_LIB_LIBX, where LIBX is the one of lib1 to libn that +# makes the function available, in uppercase. +# +# 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 +# + +include(CheckFunctionExists) +include(CheckLibraryExists) + +function(check_function_exists_may_need_library function variable) + + check_function_exists(${function} ${variable}) + + if(NOT ${variable}) + foreach(lib ${ARGN}) + string(TOUPPER ${lib} UP_LIB) + # Use new variable to prevent cache from previous step shortcircuiting + # new test + check_library_exists(${lib} ${function} "" HAVE_${function}_IN_${lib}) + if(HAVE_${function}_IN_${lib}) + set(${variable} 1 CACHE INTERNAL + "Function ${function} found in library ${lib}") + set(NEED_LIB_${UP_LIB} 1 CACHE INTERNAL + "Need to link ${lib}") + break() + endif() + endforeach() + endif() + +endfunction() \ No newline at end of file diff --git a/libssh2/cmake/CheckNonblockingSocketSupport.cmake b/libssh2/cmake/CheckNonblockingSocketSupport.cmake new file mode 100644 index 000000000..74f4776a6 --- /dev/null +++ b/libssh2/cmake/CheckNonblockingSocketSupport.cmake @@ -0,0 +1,119 @@ +include(CheckCSourceCompiles) + +# - check_nonblocking_socket_support() +# +# Check for how to set a socket to non-blocking state. There seems to exist +# four known different ways, with the one used almost everywhere being POSIX +# and XPG3, while the other different ways for different systems (old BSD, +# Windows and Amiga). +# +# One of the following variables will be set indicating the supported +# method (if any): +# HAVE_O_NONBLOCK +# HAVE_FIONBIO +# HAVE_IOCTLSOCKET +# HAVE_IOCTLSOCKET_CASE +# HAVE_SO_NONBLOCK +# HAVE_DISABLED_NONBLOCKING +# +# 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 +# +macro(check_nonblocking_socket_support) + # There are two known platforms (AIX 3.x and SunOS 4.1.x) where the + # O_NONBLOCK define is found but does not work. + check_c_source_compiles(" +#include +#include +#include + +#if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# if defined(__SVR4) || defined(__srv4__) +# define PLATFORM_SOLARIS +# else +# define PLATFORM_SUNOS4 +# endif +#endif +#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41) +# define PLATFORM_AIX_V3 +#endif + +#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__) +#error \"O_NONBLOCK does not work on this platform\" +#endif + +int main() +{ + int socket; + int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK); +}" + HAVE_O_NONBLOCK) + + if(NOT HAVE_O_NONBLOCK) + check_c_source_compiles("/* FIONBIO test (old-style unix) */ +#include +#include + +int main() +{ + int socket; + int flags = ioctl(socket, FIONBIO, &flags); +}" + HAVE_FIONBIO) + + if(NOT HAVE_FIONBIO) + check_c_source_compiles("/* ioctlsocket test (Windows) */ +#undef inline +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include +#include + +int main() +{ + SOCKET sd; + unsigned long flags = 0; + sd = socket(0, 0, 0); + ioctlsocket(sd, FIONBIO, &flags); +}" + HAVE_IOCTLSOCKET) + + if(NOT HAVE_IOCTLSOCKET) + check_c_source_compiles("/* IoctlSocket test (Amiga?) */ +#include + +int main() +{ + int socket; + int flags = IoctlSocket(socket, FIONBIO, (long)1); +}" + HAVE_IOCTLSOCKET_CASE) + + if(NOT HAVE_IOCTLSOCKET_CASE) + check_c_source_compiles("/* SO_NONBLOCK test (BeOS) */ +#include + +int main() +{ + long b = 1; + int socket; + int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); +}" + HAVE_SO_NONBLOCK) + + if(NOT HAVE_SO_NONBLOCK) + # No non-blocking socket method found + set(HAVE_DISABLED_NONBLOCKING 1) + endif() + endif() + endif() + endif() + endif() +endmacro() \ No newline at end of file diff --git a/libssh2/cmake/CopyRuntimeDependencies.cmake b/libssh2/cmake/CopyRuntimeDependencies.cmake new file mode 100644 index 000000000..083f76268 --- /dev/null +++ b/libssh2/cmake/CopyRuntimeDependencies.cmake @@ -0,0 +1,72 @@ +# Copyright (c) 2014 Alexander Lamaison +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided +# that the following conditions are met: +# +# Redistributions of source code must retain the above +# copyright notice, this list of conditions and the +# following disclaimer. +# +# 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. +# +# Neither the name of the copyright holder nor the names +# of any other contributors may be used to endorse or +# promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. + +include(CMakeParseArguments) + +function(ADD_TARGET_TO_COPY_DEPENDENCIES) + set(options) + set(oneValueArgs TARGET) + set(multiValueArgs DEPENDENCIES BEFORE_TARGETS) + cmake_parse_arguments(COPY + "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT COPY_DEPENDENCIES) + return() + endif() + + # Using a custom target to drive custom commands stops multiple + # parallel builds trying to kick off the commands at the same time + add_custom_target(${COPY_TARGET}) + + foreach(target ${COPY_BEFORE_TARGETS}) + add_dependencies(${target} ${COPY_TARGET}) + endforeach() + + foreach(dependency ${COPY_DEPENDENCIES}) + + add_custom_command( + TARGET ${COPY_TARGET} + DEPENDS ${dependency} + # Make directory first otherwise file is copied in place of + # directory instead of into it + COMMAND ${CMAKE_COMMAND} + ARGS -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + COMMAND ${CMAKE_COMMAND} + ARGS -E copy ${dependency} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + VERBATIM) + + endforeach() + +endfunction() diff --git a/libssh2/cmake/FindLibgcrypt.cmake b/libssh2/cmake/FindLibgcrypt.cmake new file mode 100644 index 000000000..44a79873d --- /dev/null +++ b/libssh2/cmake/FindLibgcrypt.cmake @@ -0,0 +1,53 @@ +# Copyright (c) 2014 Alexander Lamaison +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided +# that the following conditions are met: +# +# Redistributions of source code must retain the above +# copyright notice, this list of conditions and the +# following disclaimer. +# +# 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. +# +# Neither the name of the copyright holder nor the names +# of any other contributors may be used to endorse or +# promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +# - Try to find Libgcrypt +# This will define all or none of: +# LIBGCRYPT_FOUND - if Libgcrypt headers and library was found +# LIBGCRYPT_INCLUDE_DIRS - The Libgcrypt include directories +# LIBGCRYPT_LIBRARIES - The libraries needed to use Libgcrypt + +find_path(LIBGCRYPT_INCLUDE_DIR gcrypt.h) + +find_library(LIBGCRYPT_LIBRARY NAMES gcrypt libgcrypt) + +set(LIBGCRYPT_LIBRARIES ${LIBGCRYPT_LIBRARY}) +set(LIBGCRYPT_INCLUDE_DIRS ${LIBGCRYPT_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Libgcrypt DEFAULT_MSG + LIBGCRYPT_LIBRARY LIBGCRYPT_INCLUDE_DIR) + +mark_as_advanced(LIBGCRYPT_INCLUDE_DIR LIBGCRYPT_LIBRARY) \ No newline at end of file diff --git a/libssh2/cmake/FindmbedTLS.cmake b/libssh2/cmake/FindmbedTLS.cmake new file mode 100644 index 000000000..2f4adbc51 --- /dev/null +++ b/libssh2/cmake/FindmbedTLS.cmake @@ -0,0 +1,64 @@ +# - Try to find mbedTLS +# Once done this will define +# +# Read-Only variables +# MBEDTLS_FOUND - system has mbedTLS +# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory +# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory +# MBEDTLS_LIBRARIES - Link these to use mbedTLS +# MBEDTLS_LIBRARY - path to mbedTLS library +# MBEDX509_LIBRARY - path to mbedTLS X.509 library +# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library + +FIND_PATH(MBEDTLS_INCLUDE_DIR mbedtls/version.h) + +IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES) + # Already in cache, be silent + SET(MBEDTLS_FIND_QUIETLY TRUE) +ENDIF() + +FIND_LIBRARY(MBEDTLS_LIBRARY NAMES mbedtls libmbedtls libmbedx509) +FIND_LIBRARY(MBEDX509_LIBRARY NAMES mbedx509 libmbedx509) +FIND_LIBRARY(MBEDCRYPTO_LIBRARY NAMES mbedcrypto libmbedcrypto) + +IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY) + SET(MBEDTLS_FOUND TRUE) +ENDIF() + +IF(MBEDTLS_FOUND) + # split mbedTLS into -L and -l linker options, so we can set them for pkg-config + GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH) + GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE) + GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE) + GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE) + STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE}) + STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE}) + STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE}) + SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}") + + IF(NOT MBEDTLS_FIND_QUIETLY) + MESSAGE(STATUS "Found mbedTLS:") + FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT) + STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT}) + IF (MBEDTLSMATCH) + STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH}) + MESSAGE(STATUS " version ${MBEDTLS_VERSION}") + ENDIF(MBEDTLSMATCH) + MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}") + MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}") + MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}") + ENDIF(NOT MBEDTLS_FIND_QUIETLY) +ELSE(MBEDTLS_FOUND) + IF(MBEDTLS_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find mbedTLS") + ENDIF(MBEDTLS_FIND_REQUIRED) +ENDIF(MBEDTLS_FOUND) + +MARK_AS_ADVANCED( + MBEDTLS_INCLUDE_DIR + MBEDTLS_LIBRARY_DIR + MBEDTLS_LIBRARIES + MBEDTLS_LIBRARY + MBEDX509_LIBRARY + MBEDCRYPTO_LIBRARY +) diff --git a/libssh2/cmake/SocketLibraries.cmake b/libssh2/cmake/SocketLibraries.cmake new file mode 100644 index 000000000..bfbbd711e --- /dev/null +++ b/libssh2/cmake/SocketLibraries.cmake @@ -0,0 +1,64 @@ +# Copyright (c) 2014 Alexander Lamaison +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided +# that the following conditions are met: +# +# Redistributions of source code must retain the above +# copyright notice, this list of conditions and the +# following disclaimer. +# +# 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. +# +# Neither the name of the copyright holder nor the names +# of any other contributors may be used to endorse or +# promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +# Some systems have their socket functions in a library. +# (Solaris -lsocket/-lnsl, Windows -lws2_32). This macro appends those +# libraries to the given list +macro(append_needed_socket_libraries LIBRARIES_LIST) + if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 4) + # x86 Windows uses STDCALL for these functions, so their names are mangled, + # meaning the platform checks don't work. Hardcoding these until we get + # a better solution. + set(HAVE_SOCKET 1) + set(HAVE_SELECT 1) + set(HAVE_INET_ADDR 1) + set(NEED_LIB_WS2_32 1) + else() + check_function_exists_may_need_library(socket HAVE_SOCKET socket ws2_32) + check_function_exists_may_need_library(select HAVE_SELECT ws2_32) + check_function_exists_may_need_library(inet_addr HAVE_INET_ADDR nsl ws2_32) + endif() + + if(NEED_LIB_SOCKET) + list(APPEND ${LIBRARIES_LIST} socket) + endif() + if(NEED_LIB_NSL) + list(APPEND ${LIBRARIES_LIST} nsl) + endif() + if(NEED_LIB_WS2_32) + list(APPEND ${LIBRARIES_LIST} ws2_32) + endif() + +endmacro() \ No newline at end of file diff --git a/libssh2/cmake/Toolchain-Linux-32.cmake b/libssh2/cmake/Toolchain-Linux-32.cmake new file mode 100644 index 000000000..6aad9b1e2 --- /dev/null +++ b/libssh2/cmake/Toolchain-Linux-32.cmake @@ -0,0 +1,42 @@ +# Copyright (c) 2014 Alexander Lamaison +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided +# that the following conditions are met: +# +# Redistributions of source code must retain the above +# copyright notice, this list of conditions and the +# following disclaimer. +# +# 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. +# +# Neither the name of the copyright holder nor the names +# of any other contributors may be used to endorse or +# promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +# Cross-compile 32-bit binary on 64-bit linux host +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_SYSTEM_PROCESSOR "i386") + +set(CMAKE_CXX_COMPILER_ARG1 "-m32") +set(CMAKE_C_COMPILER_ARG1 "-m32") \ No newline at end of file diff --git a/libssh2/cmake/max_warnings.cmake b/libssh2/cmake/max_warnings.cmake new file mode 100644 index 000000000..b176d302d --- /dev/null +++ b/libssh2/cmake/max_warnings.cmake @@ -0,0 +1,23 @@ +if(MSVC) + # Use the highest warning level for visual studio. + if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + endif() + if(CMAKE_C_FLAGS MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") + endif() + + # Disable broken warnings + add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) +elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) + if(NOT CMAKE_CXX_FLAGS MATCHES "-Wall") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + endif() + if(NOT CMAKE_C_FLAGS MATCHES "-Wall") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") + endif() +endif() diff --git a/libssh2/compile b/libssh2/compile new file mode 100644 index 000000000..a85b723c7 --- /dev/null +++ b/libssh2/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libssh2/config.guess b/libssh2/config.guess new file mode 100644 index 000000000..d622a44e5 --- /dev/null +++ b/libssh2/config.guess @@ -0,0 +1,1530 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/libssh2/config.rpath b/libssh2/config.rpath new file mode 100644 index 000000000..e082db6bb --- /dev/null +++ b/libssh2/config.rpath @@ -0,0 +1,660 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2006 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 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 AC_LIBTOOL_PROG_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + darwin*) + case $cc_basename in + xlc*) + wl='-Wl,' + ;; + esac + ;; + mingw* | pw32* | os2*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + newsos6) + ;; + linux*) + case $cc_basename in + icc* | ecc*) + wl='-Wl,' + ;; + pgcc | pgf77 | pgf90) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + sco3.2v5*) + ;; + solaris*) + wl='-Wl,' + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32*) + # 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 + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we cannot use + # them. + ld_shlibs=no + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32*) + # 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 + ;; + interix3*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + linux*) + 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 + ;; + aix4* | aix5*) + 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].*|aix5*) + 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 + hardcode_direct=yes + 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*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32*) + # 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 test "$GCC" = yes ; then + : + else + case $cc_basename in + xlc*) + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd1*) + ld_shlibs=no + ;; + freebsd2.2*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + freebsd2*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | kfreebsd*-gnu | 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=: + ;; + openbsd*) + 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 + ;; + 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*) + ;; + 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 AC_LIBTOOL_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' + ;; + aix4* | aix5*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + library_names_spec='$libname.a' + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32*) + 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' + ;; + freebsd1*) + ;; + kfreebsd*-gnu) + 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' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix3*) + 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*) + 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' + ;; + 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' + ;; + 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=/' <. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/libssh2/configure b/libssh2/configure new file mode 100644 index 000000000..0fd2d09b8 --- /dev/null +++ b/libssh2/configure @@ -0,0 +1,20943 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for libssh2 -. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + 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 + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: libssh2-devel@cool.haxx.se about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='libssh2' +PACKAGE_TARNAME='libssh2' +PACKAGE_VERSION='-' +PACKAGE_STRING='libssh2 -' +PACKAGE_BUGREPORT='libssh2-devel@cool.haxx.se' +PACKAGE_URL='' + +ac_unique_file="src" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +ALLOCA +HAVE_SYS_UN_H_FALSE +HAVE_SYS_UN_H_TRUE +BUILD_EXAMPLES_FALSE +BUILD_EXAMPLES_TRUE +LIBSREQUIRED +LIBZ_PREFIX +LTLIBZ +LIBZ +HAVE_LIBZ +OS400QC3_FALSE +OS400QC3_TRUE +MBEDTLS_FALSE +MBEDTLS_TRUE +LIBGCRYPT_FALSE +LIBGCRYPT_TRUE +WINCNG_FALSE +WINCNG_TRUE +OPENSSL_FALSE +OPENSSL_TRUE +LIBSSL_PREFIX +LTLIBSSL +LIBSSL +HAVE_LIBSSL +LIBMBEDTLS_PREFIX +LTLIBMBEDTLS +LIBMBEDTLS +HAVE_LIBMBEDTLS +LIBCRYPT32_PREFIX +LTLIBCRYPT32 +LIBCRYPT32 +HAVE_LIBCRYPT32 +LIBBCRYPT_PREFIX +LTLIBBCRYPT +LIBBCRYPT +HAVE_LIBBCRYPT +LIBGCRYPT_PREFIX +LTLIBGCRYPT +LIBGCRYPT +HAVE_LIBGCRYPT +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +LIBTOOL +OBJDUMP +DLLTOOL +AS +SSHD_FALSE +SSHD_TRUE +SSHD +LN_S +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBSSH2VER +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +SED +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_maintainer_mode +enable_silent_rules +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_largefile +with_openssl +with_libgcrypt +enable_rpath +with_libgcrypt_prefix +with_wincng +with_libbcrypt_prefix +with_libcrypt32_prefix +with_mbedtls +with_libmbedtls_prefix +with_libz +with_libssl_prefix +with_libz_prefix +enable_crypt_none +enable_mac_none +enable_gex_new +enable_clear_memory +enable_debug +enable_hidden_symbols +enable_examples_build +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +LT_SYS_LIBRARY_PATH' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures libssh2 - to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/libssh2] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of libssh2 -:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-largefile omit support for large files + --disable-rpath do not hardcode runtime library paths + --enable-crypt-none Permit "none" cipher -- NOT RECOMMENDED + --enable-mac-none Permit "none" MAC -- NOT RECOMMENDED + --disable-gex-new Disable "new" diffie-hellman-group-exchange-sha1 + method + --disable-clear-memory Disable clearing of memory before being freed + --enable-debug Enable pedantic and debug options + --disable-debug Disable debug options + --enable-hidden-symbols Hide internal symbols in library + --disable-hidden-symbols + Leave all symbols with default visibility in library + --enable-examples-build Build example applications (this is the default) + --disable-examples-build + Do not build example applications + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-openssl Use OpenSSL for crypto + --with-libgcrypt Use libgcrypt for crypto + --with-gnu-ld assume the C compiler uses GNU ld default=no + --with-libgcrypt-prefix[=DIR] search for libgcrypt in DIR/include and DIR/lib + --without-libgcrypt-prefix don't search for libgcrypt in includedir and libdir + --with-wincng Use Windows CNG for crypto + --with-libbcrypt-prefix[=DIR] search for libbcrypt in DIR/include and DIR/lib + --without-libbcrypt-prefix don't search for libbcrypt in includedir and libdir + --with-libcrypt32-prefix[=DIR] search for libcrypt32 in DIR/include and DIR/lib + --without-libcrypt32-prefix don't search for libcrypt32 in includedir and libdir + --with-mbedtls Use mbedTLS for crypto + --with-libmbedtls-prefix[=DIR] search for libmbedtls in DIR/include and DIR/lib + --without-libmbedtls-prefix don't search for libmbedtls in includedir and libdir + --with-libz Use zlib for compression + --with-libssl-prefix[=DIR] search for libssl in DIR/include and DIR/lib + --without-libssl-prefix don't search for libssl in includedir and libdir + --with-libz-prefix[=DIR] search for libz in DIR/include and DIR/lib + --without-libz-prefix don't search for libz in includedir and libdir + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +libssh2 configure - +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $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_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ----------------------------------------- ## +## Report this to libssh2-devel@cool.haxx.se ## +## ----------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by libssh2 $as_me -, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_config_headers="$ac_config_headers src/libssh2_config.h" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + +# Extract the first word of "sed", so it can be a program name with args. +set dummy sed; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SED in + [\\/]* | ?:[\\/]*) + ac_cv_path_SED="$SED" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_SED" && ac_cv_path_SED="sed-was-not-found-by-configure" + ;; +esac +fi +SED=$ac_cv_path_SED +if test -n "$SED"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED" >&5 +$as_echo "$SED" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + +if test "x$SED" = "xsed-was-not-found-by-configure"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: sed was not found, this may ruin your chances to build fine" >&5 +$as_echo "$as_me: WARNING: sed was not found, this may ruin your chances to build fine" >&2;} +fi + +LIBSSH2VER=`$SED -ne 's/^#define LIBSSH2_VERSION *"\(.*\)"/\1/p' ${srcdir}/include/libssh2.h` +am__api_version='1.15' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='libssh2' + VERSION='-' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking libssh2 version" >&5 +$as_echo_n "checking libssh2 version... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBSSH2VER" >&5 +$as_echo "$LIBSSH2VER" >&6; } + + + +AB_VERSION=$LIBSSH2VER + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + + + + + if test -z "$AB_PACKAGE"; then + AB_PACKAGE=${PACKAGE_NAME:-$PACKAGE} + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: autobuild project... $AB_PACKAGE" >&5 +$as_echo "$as_me: autobuild project... $AB_PACKAGE" >&6;} + + if test -z "$AB_VERSION"; then + AB_VERSION=${PACKAGE_VERSION:-$VERSION} + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: autobuild revision... $AB_VERSION" >&5 +$as_echo "$as_me: autobuild revision... $AB_VERSION" >&6;} + + hostname=`hostname` + if test "$hostname"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: autobuild hostname... $hostname" >&5 +$as_echo "$as_me: autobuild hostname... $hostname" >&6;} + fi + + + + date=`date +%Y%m%d-%H%M%S` + if test "$?" != 0; then + date=`date` + fi + if test "$date"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: autobuild timestamp... $date" >&5 +$as_echo "$as_me: autobuild timestamp... $date" >&6;} + fi + + +# Check for the OS. +# Daniel's note: this should not be necessary and we need to work to +# get this removed. + +case "$host" in + *-mingw*) + CFLAGS="$CFLAGS -DLIBSSH2_WIN32" + LIBS="$LIBS -lws2_32" + ;; + *-cygwin) + CFLAGS="$CFLAGS -DLIBSSH2_WIN32" + ;; + *darwin*) + CFLAGS="$CFLAGS -DLIBSSH2_DARWIN" + ;; + *hpux*) + ;; + *osf*) + CFLAGS="$CFLAGS -D_POSIX_PII_SOCKET" + ;; + *) + ;; +esac + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default" +if test "x$ac_cv_type_long_long" = xyes; then : + +$as_echo "#define HAVE_LONGLONG 1" >>confdefs.h + + longlong="yes" + +fi + + + + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if _REENTRANT is already defined" >&5 +$as_echo_n "checking if _REENTRANT is already defined... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + +int +main () +{ + +#ifdef _REENTRANT + int dummy=1; +#else + force compilation error +#endif + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + tmp_reentrant_initially_defined="yes" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + tmp_reentrant_initially_defined="no" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # + if test "$tmp_reentrant_initially_defined" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if _REENTRANT is actually needed" >&5 +$as_echo_n "checking if _REENTRANT is actually needed... " >&6; } + + case $host in + *-*-solaris* | *-*-hpux*) + tmp_need_reentrant="yes" + ;; + *) + tmp_need_reentrant="no" + ;; + esac + + + if test "$tmp_need_reentrant" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if _REENTRANT is onwards defined" >&5 +$as_echo_n "checking if _REENTRANT is onwards defined... " >&6; } + if test "$tmp_reentrant_initially_defined" = "yes" || + test "$tmp_need_reentrant" = "yes"; then + + +$as_echo "#define NEED_REENTRANT 1" >>confdefs.h + +cat >>confdefs.h <<_EOF +#ifndef _REENTRANT +# define _REENTRANT +#endif +_EOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + # + + +# Some systems (Solaris?) have socket() in -lsocket. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 +$as_echo_n "checking for library containing socket... " >&6; } +if ${ac_cv_search_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +for ac_lib in '' socket; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_socket=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_socket+:} false; then : + break +fi +done +if ${ac_cv_search_socket+:} false; then : + +else + ac_cv_search_socket=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 +$as_echo "$ac_cv_search_socket" >&6; } +ac_res=$ac_cv_search_socket +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + +# Solaris has inet_addr() in -lnsl. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_addr" >&5 +$as_echo_n "checking for library containing inet_addr... " >&6; } +if ${ac_cv_search_inet_addr+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char inet_addr (); +int +main () +{ +return inet_addr (); + ; + return 0; +} +_ACEOF +for ac_lib in '' nsl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_inet_addr=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_inet_addr+:} false; then : + break +fi +done +if ${ac_cv_search_inet_addr+:} false; then : + +else + ac_cv_search_inet_addr=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_addr" >&5 +$as_echo "$ac_cv_search_inet_addr" >&6; } +ac_res=$ac_cv_search_inet_addr +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +for ac_prog in sshd +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SSHD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SSHD in + [\\/]* | ?:[\\/]*) + ac_cv_path_SSHD="$SSHD" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/libexec$PATH_SEPARATOR /usr/sbin$PATH_SEPARATOR/usr/etc$PATH_SEPARATOR/etc +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SSHD="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +SSHD=$ac_cv_path_SSHD +if test -n "$SSHD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SSHD" >&5 +$as_echo "$SSHD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$SSHD" && break +done + + if test -n "$SSHD"; then + SSHD_TRUE= + SSHD_FALSE='#' +else + SSHD_TRUE='#' + SSHD_FALSE= +fi + +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + 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. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname 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 yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + 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 yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # 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. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + 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 + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + 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 + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + 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 + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + 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. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + 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 + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # 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 yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # 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*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + link_all_deplibs=no + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + + +found_crypto=none + +# Configure parameters + +# Check whether --with-openssl was given. +if test "${with_openssl+set}" = set; then : + withval=$with_openssl; use_openssl=$withval +else + use_openssl=auto +fi + + + 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" + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 +$as_echo_n "checking for ld used by GCC... " >&6; } + 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${acl_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + 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 +fi + +LD="$acl_cv_path_LD" +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${acl_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$acl_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +$as_echo_n "checking for shared library run path origin... " >&6; } +if ${acl_cv_rpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + 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 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +$as_echo "$acl_cv_rpath" >&6; } + 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" + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; : +else + enable_rpath=yes +fi + + + + acl_libdirstem=lib + 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 ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + + +# Check whether --with-libgcrypt was given. +if test "${with_libgcrypt+set}" = set; then : + withval=$with_libgcrypt; use_libgcrypt=$withval + + + old_LDFLAGS=$LDFLAGS + old_CFLAGS=$CFLAGS + if test -n "$use_libgcrypt" && test "$use_libgcrypt" != "no"; then + LDFLAGS="$LDFLAGS -L$use_libgcrypt/lib" + CFLAGS="$CFLAGS -I$use_libgcrypt/include" + fi + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libgcrypt-prefix was given. +if test "${with_libgcrypt_prefix+set}" = set; then : + withval=$with_libgcrypt_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi + +fi + + LIBGCRYPT= + LTLIBGCRYPT= + INCGCRYPT= + LIBGCRYPT_PREFIX= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='gcrypt ' + 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" + 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" || LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }$value" + else + : + fi + else + 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" + 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 + 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 $LTLIBGCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + 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 + 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 + LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_so" + else + 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 + if test "$acl_hardcode_direct" = yes; then + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_so" + 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 + haveit= + for x in $LDFLAGS $LIBGCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_so" + else + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$found_a" + else + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + LIBGCRYPT_PREFIX="$basedir" + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + 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 $INCGCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + INCGCRYPT="${INCGCRYPT}${INCGCRYPT:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; 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 $LIBGCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBGCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + 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 + 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*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$dep" + LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }$dep" + ;; + esac + done + fi + else + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }-l$name" + LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBGCRYPT="${LIBGCRYPT}${LIBGCRYPT:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBGCRYPT="${LTLIBGCRYPT}${LTLIBGCRYPT:+ }-R$found_dir" + done + fi + + + ac_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCGCRYPT; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libgcrypt" >&5 +$as_echo_n "checking for libgcrypt... " >&6; } +if ${ac_cv_libgcrypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBGCRYPT" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_libgcrypt=yes +else + ac_cv_libgcrypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libgcrypt" >&5 +$as_echo "$ac_cv_libgcrypt" >&6; } + if test "$ac_cv_libgcrypt" = yes; then + HAVE_LIBGCRYPT=yes + +$as_echo "#define HAVE_LIBGCRYPT 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libgcrypt" >&5 +$as_echo_n "checking how to link with libgcrypt... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBGCRYPT" >&5 +$as_echo "$LIBGCRYPT" >&6; } + else + HAVE_LIBGCRYPT=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBGCRYPT= + LTLIBGCRYPT= + LIBGCRYPT_PREFIX= + fi + + + + + + + + + if test "$ac_cv_libgcrypt" = "yes"; then + +$as_echo "#define LIBSSH2_LIBGCRYPT 1" >>confdefs.h + + LIBSREQUIRED= # libgcrypt doesn't provide a .pc file. sad face. + LIBS="$LIBS -lgcrypt" + found_crypto=libgcrypt + else + # restore + LDFLAGS=$old_LDFLAGS + CFLAGS=$old_CFLAGS + fi + + +else + use_libgcrypt=auto +fi + + +# Check whether --with-wincng was given. +if test "${with_wincng+set}" = set; then : + withval=$with_wincng; use_wincng=$withval + + + # Look for Windows Cryptography API: Next Generation + + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libbcrypt-prefix was given. +if test "${with_libbcrypt_prefix+set}" = set; then : + withval=$with_libbcrypt_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi + +fi + + LIBBCRYPT= + LTLIBBCRYPT= + INCBCRYPT= + LIBBCRYPT_PREFIX= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='bcrypt ' + 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" + 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" || LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }$value" + else + : + fi + else + 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" + 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 + 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 $LTLIBBCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + 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 + 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 + LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_so" + else + 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 + if test "$acl_hardcode_direct" = yes; then + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_so" + 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 + haveit= + for x in $LDFLAGS $LIBBCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_so" + else + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$found_a" + else + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + LIBBCRYPT_PREFIX="$basedir" + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + 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 $INCBCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + INCBCRYPT="${INCBCRYPT}${INCBCRYPT:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; 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 $LIBBCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBBCRYPT; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + 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 + 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*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$dep" + LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }$dep" + ;; + esac + done + fi + else + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }-l$name" + LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBBCRYPT="${LIBBCRYPT}${LIBBCRYPT:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBBCRYPT="${LTLIBBCRYPT}${LTLIBBCRYPT:+ }-R$found_dir" + done + fi + + + ac_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCBCRYPT; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libbcrypt" >&5 +$as_echo_n "checking for libbcrypt... " >&6; } +if ${ac_cv_libbcrypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBBCRYPT" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_libbcrypt=yes +else + ac_cv_libbcrypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libbcrypt" >&5 +$as_echo "$ac_cv_libbcrypt" >&6; } + if test "$ac_cv_libbcrypt" = yes; then + HAVE_LIBBCRYPT=yes + +$as_echo "#define HAVE_LIBBCRYPT 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libbcrypt" >&5 +$as_echo_n "checking how to link with libbcrypt... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBBCRYPT" >&5 +$as_echo "$LIBBCRYPT" >&6; } + else + HAVE_LIBBCRYPT=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBBCRYPT= + LTLIBBCRYPT= + LIBBCRYPT_PREFIX= + fi + + + + + + + + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libcrypt32-prefix was given. +if test "${with_libcrypt32_prefix+set}" = set; then : + withval=$with_libcrypt32_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi + +fi + + LIBCRYPT32= + LTLIBCRYPT32= + INCCRYPT32= + LIBCRYPT32_PREFIX= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='crypt32 ' + 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" + 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" || LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBCRYPT32="${LTLIBCRYPT32}${LTLIBCRYPT32:+ }$value" + else + : + fi + else + 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" + 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 + 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 $LTLIBCRYPT32; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + 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 + 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 + LTLIBCRYPT32="${LTLIBCRYPT32}${LTLIBCRYPT32:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }$found_so" + else + 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 + if test "$acl_hardcode_direct" = yes; then + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }$found_so" + 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 + haveit= + for x in $LDFLAGS $LIBCRYPT32; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }$found_so" + else + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }$found_a" + else + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + LIBCRYPT32_PREFIX="$basedir" + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + 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 $INCCRYPT32; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + INCCRYPT32="${INCCRYPT32}${INCCRYPT32:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; 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 $LIBCRYPT32; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBCRYPT32; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LTLIBCRYPT32="${LTLIBCRYPT32}${LTLIBCRYPT32:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + 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 + 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*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }$dep" + LTLIBCRYPT32="${LTLIBCRYPT32}${LTLIBCRYPT32:+ }$dep" + ;; + esac + done + fi + else + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }-l$name" + LTLIBCRYPT32="${LTLIBCRYPT32}${LTLIBCRYPT32:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBCRYPT32="${LIBCRYPT32}${LIBCRYPT32:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBCRYPT32="${LTLIBCRYPT32}${LTLIBCRYPT32:+ }-R$found_dir" + done + fi + + + ac_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCCRYPT32; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcrypt32" >&5 +$as_echo_n "checking for libcrypt32... " >&6; } +if ${ac_cv_libcrypt32+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBCRYPT32" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_libcrypt32=yes +else + ac_cv_libcrypt32=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libcrypt32" >&5 +$as_echo "$ac_cv_libcrypt32" >&6; } + if test "$ac_cv_libcrypt32" = yes; then + HAVE_LIBCRYPT32=yes + +$as_echo "#define HAVE_LIBCRYPT32 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libcrypt32" >&5 +$as_echo_n "checking how to link with libcrypt32... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBCRYPT32" >&5 +$as_echo "$LIBCRYPT32" >&6; } + else + HAVE_LIBCRYPT32=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBCRYPT32= + LTLIBCRYPT32= + LIBCRYPT32_PREFIX= + fi + + + + + + + + for ac_header in ntdef.h ntstatus.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " + #include + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + ac_fn_c_check_decl "$LINENO" "SecureZeroMemory" "ac_cv_have_decl_SecureZeroMemory" " + #include + +" +if test "x$ac_cv_have_decl_SecureZeroMemory" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SECUREZEROMEMORY $ac_have_decl +_ACEOF + + + if test "$ac_cv_libbcrypt" = "yes"; then + +$as_echo "#define LIBSSH2_WINCNG 1" >>confdefs.h + + LIBSREQUIRED= # wincng doesn't provide a .pc file. sad face. + LIBS="$LIBS -lbcrypt" + if test "$ac_cv_libcrypt32" = "yes"; then + LIBS="$LIBS -lcrypt32" + fi + found_crypto="Windows Cryptography API: Next Generation" + if test "$ac_cv_have_decl_SecureZeroMemory" = "yes"; then + support_clear_memory=yes + fi + fi + + +else + use_wincng=auto +fi + + +# Check whether --with-mbedtls was given. +if test "${with_mbedtls+set}" = set; then : + withval=$with_mbedtls; use_mbedtls=$withval + + + old_LDFLAGS=$LDFLAGS + old_CFLAGS=$CFLAGS + if test -n "$use_mbedtls" && test "$use_mbedtls" != "no"; then + LDFLAGS="$LDFLAGS -L$use_mbedtls/lib" + CFLAGS="$CFLAGS -I$use_mbedtls/include" + fi + + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libmbedtls-prefix was given. +if test "${with_libmbedtls_prefix+set}" = set; then : + withval=$with_libmbedtls_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi + +fi + + LIBMBEDTLS= + LTLIBMBEDTLS= + INCMBEDTLS= + LIBMBEDTLS_PREFIX= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='mbedtls ' + 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" + 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" || LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBMBEDTLS="${LTLIBMBEDTLS}${LTLIBMBEDTLS:+ }$value" + else + : + fi + else + 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" + 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 + 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 $LTLIBMBEDTLS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + 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 + 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 + LTLIBMBEDTLS="${LTLIBMBEDTLS}${LTLIBMBEDTLS:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }$found_so" + else + 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 + if test "$acl_hardcode_direct" = yes; then + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }$found_so" + 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 + haveit= + for x in $LDFLAGS $LIBMBEDTLS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }$found_so" + else + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }$found_a" + else + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + LIBMBEDTLS_PREFIX="$basedir" + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + 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 $INCMBEDTLS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + INCMBEDTLS="${INCMBEDTLS}${INCMBEDTLS:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; 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 $LIBMBEDTLS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBMBEDTLS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LTLIBMBEDTLS="${LTLIBMBEDTLS}${LTLIBMBEDTLS:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + 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 + 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*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }$dep" + LTLIBMBEDTLS="${LTLIBMBEDTLS}${LTLIBMBEDTLS:+ }$dep" + ;; + esac + done + fi + else + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }-l$name" + LTLIBMBEDTLS="${LTLIBMBEDTLS}${LTLIBMBEDTLS:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBMBEDTLS="${LIBMBEDTLS}${LIBMBEDTLS:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBMBEDTLS="${LTLIBMBEDTLS}${LTLIBMBEDTLS:+ }-R$found_dir" + done + fi + + + ac_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCMBEDTLS; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmbedtls" >&5 +$as_echo_n "checking for libmbedtls... " >&6; } +if ${ac_cv_libmbedtls+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBMBEDTLS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_libmbedtls=yes +else + ac_cv_libmbedtls=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libmbedtls" >&5 +$as_echo "$ac_cv_libmbedtls" >&6; } + if test "$ac_cv_libmbedtls" = yes; then + HAVE_LIBMBEDTLS=yes + +$as_echo "#define HAVE_LIBMBEDTLS 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libmbedtls" >&5 +$as_echo_n "checking how to link with libmbedtls... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBMBEDTLS" >&5 +$as_echo "$LIBMBEDTLS" >&6; } + else + HAVE_LIBMBEDTLS=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBMBEDTLS= + LTLIBMBEDTLS= + LIBMBEDTLS_PREFIX= + fi + + + + + + + + + if test "$ac_cv_libmbedtls" = "yes"; then + +$as_echo "#define LIBSSH2_MBEDTLS 1" >>confdefs.h + + LIBSREQUIRED= # mbedtls doesn't provide a .pc file + LIBS="$LIBS -lmbedtls -lmbedcrypto" + found_crypto=libmbedtls + support_clear_memory=yes + else + # restore + LDFLAGS=$old_LDFLAGS + CFLAGS=$old_CFLAGS + fi + + +else + use_mbedtls=auto + +fi + + +# Check whether --with-libz was given. +if test "${with_libz+set}" = set; then : + withval=$with_libz; use_libz=$withval +else + use_libz=auto +fi + + +support_clear_memory=no + +# Look for OpenSSL +if test "$found_crypto" = "none" && test "$use_openssl" != "no"; then + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libssl-prefix was given. +if test "${with_libssl_prefix+set}" = set; then : + withval=$with_libssl_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi + +fi + + LIBSSL= + LTLIBSSL= + INCSSL= + LIBSSL_PREFIX= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='ssl crypto' + 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" + 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" || LIBSSL="${LIBSSL}${LIBSSL:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }$value" + else + : + fi + else + 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" + 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 + 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 $LTLIBSSL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + 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 + 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 + LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + LIBSSL="${LIBSSL}${LIBSSL:+ }$found_so" + else + 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 + if test "$acl_hardcode_direct" = yes; then + LIBSSL="${LIBSSL}${LIBSSL:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBSSL="${LIBSSL}${LIBSSL:+ }$found_so" + 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 + haveit= + for x in $LDFLAGS $LIBSSL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBSSL="${LIBSSL}${LIBSSL:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBSSL="${LIBSSL}${LIBSSL:+ }$found_so" + else + LIBSSL="${LIBSSL}${LIBSSL:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBSSL="${LIBSSL}${LIBSSL:+ }$found_a" + else + LIBSSL="${LIBSSL}${LIBSSL:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + LIBSSL_PREFIX="$basedir" + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + 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 $INCSSL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + INCSSL="${INCSSL}${INCSSL:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; 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 $LIBSSL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LIBSSL="${LIBSSL}${LIBSSL:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBSSL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + 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 + 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*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBSSL="${LIBSSL}${LIBSSL:+ }$dep" + LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }$dep" + ;; + esac + done + fi + else + LIBSSL="${LIBSSL}${LIBSSL:+ }-l$name" + LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBSSL="${LIBSSL}${LIBSSL:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBSSL="${LIBSSL}${LIBSSL:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBSSL="${LTLIBSSL}${LTLIBSSL:+ }-R$found_dir" + done + fi + + + ac_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCSSL; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libssl" >&5 +$as_echo_n "checking for libssl... " >&6; } +if ${ac_cv_libssl+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBSSL" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_libssl=yes +else + ac_cv_libssl=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libssl" >&5 +$as_echo "$ac_cv_libssl" >&6; } + if test "$ac_cv_libssl" = yes; then + HAVE_LIBSSL=yes + +$as_echo "#define HAVE_LIBSSL 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libssl" >&5 +$as_echo_n "checking how to link with libssl... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBSSL" >&5 +$as_echo "$LIBSSL" >&6; } + else + HAVE_LIBSSL=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBSSL= + LTLIBSSL= + LIBSSL_PREFIX= + fi + + + + + + + +fi +if test "$ac_cv_libssl" = "yes"; then + +$as_echo "#define LIBSSH2_OPENSSL 1" >>confdefs.h + + LIBSREQUIRED=libssl,libcrypto + + # Not all OpenSSL have AES-CTR functions. + save_LIBS="$LIBS" + LIBS="$LIBS $LIBSSL" + for ac_func in EVP_aes_128_ctr +do : + ac_fn_c_check_func "$LINENO" "EVP_aes_128_ctr" "ac_cv_func_EVP_aes_128_ctr" +if test "x$ac_cv_func_EVP_aes_128_ctr" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EVP_AES_128_CTR 1 +_ACEOF + +fi +done + + LIBS="$save_LIBS" + + found_crypto="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})" +fi + + if test "$ac_cv_libssl" = "yes"; then + OPENSSL_TRUE= + OPENSSL_FALSE='#' +else + OPENSSL_TRUE='#' + OPENSSL_FALSE= +fi + + if test "$ac_cv_libbcrypt" = "yes"; then + WINCNG_TRUE= + WINCNG_FALSE='#' +else + WINCNG_TRUE='#' + WINCNG_FALSE= +fi + + if test "$ac_cv_libgcrypt" = "yes"; then + LIBGCRYPT_TRUE= + LIBGCRYPT_FALSE='#' +else + LIBGCRYPT_TRUE='#' + LIBGCRYPT_FALSE= +fi + + if test "$ac_cv_libmbedtls" = "yes"; then + MBEDTLS_TRUE= + MBEDTLS_FALSE='#' +else + MBEDTLS_TRUE='#' + MBEDTLS_FALSE= +fi + + if false; then + OS400QC3_TRUE= + OS400QC3_FALSE='#' +else + OS400QC3_TRUE='#' + OS400QC3_FALSE= +fi + + +# Check if crypto library was found +if test "$found_crypto" = "none"; then + as_fn_error $? "No crypto library found! +Try --with-libssl-prefix=PATH + or --with-libgcrypt-prefix=PATH + or --with-libmbedtls-prefix=PATH + or --with-wincng on Windows\ +" "$LINENO" 5 +fi + +# Look for Libz +if test "$use_libz" != "no"; then + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libz-prefix was given. +if test "${with_libz_prefix+set}" = set; then : + withval=$with_libz_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi + +fi + + LIBZ= + LTLIBZ= + INCZ= + LIBZ_PREFIX= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='z ' + 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" + 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" || LIBZ="${LIBZ}${LIBZ:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBZ="${LTLIBZ}${LTLIBZ:+ }$value" + else + : + fi + else + 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" + 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 + 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 $LTLIBZ; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + 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 + 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 + LTLIBZ="${LTLIBZ}${LTLIBZ:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then + LIBZ="${LIBZ}${LIBZ:+ }$found_so" + else + 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 + if test "$acl_hardcode_direct" = yes; then + LIBZ="${LIBZ}${LIBZ:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBZ="${LIBZ}${LIBZ:+ }$found_so" + 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 + haveit= + for x in $LDFLAGS $LIBZ; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBZ="${LIBZ}${LIBZ:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBZ="${LIBZ}${LIBZ:+ }$found_so" + else + LIBZ="${LIBZ}${LIBZ:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBZ="${LIBZ}${LIBZ:+ }$found_a" + else + LIBZ="${LIBZ}${LIBZ:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + LIBZ_PREFIX="$basedir" + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + 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 $INCZ; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + INCZ="${INCZ}${INCZ:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; 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 $LIBZ; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LIBZ="${LIBZ}${LIBZ:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBZ; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + 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 + LTLIBZ="${LTLIBZ}${LTLIBZ:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + 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 + 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*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBZ="${LIBZ}${LIBZ:+ }$dep" + LTLIBZ="${LTLIBZ}${LTLIBZ:+ }$dep" + ;; + esac + done + fi + else + LIBZ="${LIBZ}${LIBZ:+ }-l$name" + LTLIBZ="${LTLIBZ}${LTLIBZ:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBZ="${LIBZ}${LIBZ:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBZ="${LIBZ}${LIBZ:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBZ="${LTLIBZ}${LTLIBZ:+ }-R$found_dir" + done + fi + + + ac_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCZ; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libz" >&5 +$as_echo_n "checking for libz... " >&6; } +if ${ac_cv_libz+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBZ" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_libz=yes +else + ac_cv_libz=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libz" >&5 +$as_echo "$ac_cv_libz" >&6; } + if test "$ac_cv_libz" = yes; then + HAVE_LIBZ=yes + +$as_echo "#define HAVE_LIBZ 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libz" >&5 +$as_echo_n "checking how to link with libz... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBZ" >&5 +$as_echo "$LIBZ" >&6; } + else + HAVE_LIBZ=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBZ= + LTLIBZ= + LIBZ_PREFIX= + fi + + + + + + + + if test "$ac_cv_libz" != yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Cannot find zlib, disabling compression" >&5 +$as_echo "$as_me: Cannot find zlib, disabling compression" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Try --with-libz-prefix=PATH if you know you have it" >&5 +$as_echo "$as_me: Try --with-libz-prefix=PATH if you know you have it" >&6;} + else + +$as_echo "#define LIBSSH2_HAVE_ZLIB 1" >>confdefs.h + + if test "${LIBSREQUIRED}" != ""; then + LIBSREQUIRED="${LIBSREQUIRED}," + fi + LIBSREQUIRED="${LIBSREQUIRED}zlib" + fi +fi + + + +# +# Optional Settings +# +# Check whether --enable-crypt-none was given. +if test "${enable_crypt_none+set}" = set; then : + enableval=$enable_crypt_none; +$as_echo "#define LIBSSH2_CRYPT_NONE 1" >>confdefs.h + +fi + + +# Check whether --enable-mac-none was given. +if test "${enable_mac_none+set}" = set; then : + enableval=$enable_mac_none; +$as_echo "#define LIBSSH2_MAC_NONE 1" >>confdefs.h + +fi + + +# Check whether --enable-gex-new was given. +if test "${enable_gex_new+set}" = set; then : + enableval=$enable_gex_new; GEX_NEW=$enableval +fi + +if test "$GEX_NEW" != "no"; then + +$as_echo "#define LIBSSH2_DH_GEX_NEW 1" >>confdefs.h + +fi + +# Check whether --enable-clear-memory was given. +if test "${enable_clear_memory+set}" = set; then : + enableval=$enable_clear_memory; CLEAR_MEMORY=$enableval +fi + +if test "$CLEAR_MEMORY" != "no"; then + if test "$support_clear_memory" = "yes"; then + +$as_echo "#define LIBSSH2_CLEAR_MEMORY 1" >>confdefs.h + + enable_clear_memory=yes + else + if test "$CLEAR_MEMORY" = "yes"; then + as_fn_error $? "secure clearing/zeroing of memory is not supported by the selected crypto backend" "$LINENO" 5 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: secure clearing/zeroing of memory is not supported by the selected crypto backend" >&5 +$as_echo "$as_me: WARNING: secure clearing/zeroing of memory is not supported by the selected crypto backend" >&2;} + fi + enable_clear_memory=unsupported + fi +else + if test "$support_clear_memory" = "yes"; then + enable_clear_memory=no + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: secure clearing/zeroing of memory is not supported by the selected crypto backend" >&5 +$as_echo "$as_me: WARNING: secure clearing/zeroing of memory is not supported by the selected crypto backend" >&2;} + enable_clear_memory=unsupported + fi +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable pedantic and debug compiler options" >&5 +$as_echo_n "checking whether to enable pedantic and debug compiler options... " >&6; } +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; case "$enable_debug" in + no) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + enable_debug=yes + CPPFLAGS="$CPPFLAGS -DLIBSSH2DEBUG" + CFLAGS="$CFLAGS -g" + + + if test "z$ICC" = "z"; then + + ICC="no" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for icc in use" >&5 +$as_echo_n "checking for icc in use... " >&6; } + if test "$GCC" = "yes"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +__INTEL_COMPILER +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "^__INTEL_COMPILER" >/dev/null 2>&1; then : + ICC="no" +else + ICC="yes" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + +fi +rm -f conftest* + + fi + if test "$ICC" = "no"; then + # this is not ICC + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + + fi + + if test "$GCC" = "yes"; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking gcc version" >&5 +$as_echo_n "checking gcc version... " >&6; } + gccver=`$CC -dumpversion` + num1=`echo $gccver | cut -d . -f1` + num2=`echo $gccver | cut -d . -f2` + gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gccver" >&5 +$as_echo "$gccver" >&6; } + + if test "$ICC" = "yes"; then + + + WARN="-wd279,269,981,1418,1419" + + if test "$gccnum" -gt "600"; then + WARN="-Wall $WARN" + fi + else WARN="-W -Wall -Wwrite-strings -pedantic -Wpointer-arith -Wnested-externs -Winline -Wmissing-prototypes" + + + if test "$gccnum" -ge "207"; then + WARN="$WARN -Wmissing-declarations" + fi + + if test "$gccnum" -gt "295"; then + WARN="$WARN -Wundef -Wno-long-long -Wsign-compare" + fi + + if test "$gccnum" -ge "296"; then + WARN="$WARN -Wfloat-equal" + fi + + if test "$gccnum" -gt "296"; then + WARN="$WARN -Wno-format-nonliteral" + fi + + + if test "$gccnum" -ge "303"; then + WARN="$WARN -Wendif-labels -Wstrict-prototypes" + fi + + if test "$gccnum" -ge "304"; then + # try these on gcc 3.4 + WARN="$WARN -Wdeclaration-after-statement" + fi + + for flag in $CPPFLAGS; do + case "$flag" in + -I*) + add=`echo $flag | sed 's/^-I/-isystem /g'` + WARN="$WARN $add" + ;; + esac + done + + fi + CFLAGS="$CFLAGS $WARN" + + { $as_echo "$as_me:${as_lineno-$LINENO}: Added this set of compiler options: $WARN" >&5 +$as_echo "$as_me: Added this set of compiler options: $WARN" >&6;} + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Added no extra compiler options" >&5 +$as_echo "$as_me: Added no extra compiler options" >&6;} + + fi + NEWFLAGS="" + for flag in $CFLAGS; do + case "$flag" in + -O*) + ;; + *) + NEWFLAGS="$NEWFLAGS $flag" + ;; + esac + done + CFLAGS=$NEWFLAGS + + + ;; + esac + +else + enable_debug=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable hidden symbols in the library" >&5 +$as_echo_n "checking whether to enable hidden symbols in the library... " >&6; } +# Check whether --enable-hidden-symbols was given. +if test "${enable_hidden_symbols+set}" = set; then : + enableval=$enable_hidden_symbols; case "$enableval" in + no) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports it" >&5 +$as_echo_n "checking whether $CC supports it... " >&6; } + if test "$GCC" = yes ; then + if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define LIBSSH2_API __attribute__ ((visibility (\"default\")))" >>confdefs.h + + CFLAGS="$CFLAGS -fvisibility=hidden" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + + else + if $CC 2>&1 | grep flags >/dev/null && $CC -flags | grep xldscope= >/dev/null ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define LIBSSH2_API __global" >>confdefs.h + + CFLAGS="$CFLAGS -xldscope=hidden" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + ;; + esac +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi + + +# Build example applications? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build example applications" >&5 +$as_echo_n "checking whether to build example applications... " >&6; } +# Check whether --enable-examples-build was given. +if test "${enable_examples_build+set}" = set; then : + enableval=$enable_examples_build; case "$enableval" in + no | false) + build_examples='no' + ;; + *) + build_examples='yes' + ;; +esac +else + build_examples='yes' +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_examples" >&5 +$as_echo "$build_examples" >&6; } + if test "x$build_examples" != "xno"; then + BUILD_EXAMPLES_TRUE= + BUILD_EXAMPLES_FALSE='#' +else + BUILD_EXAMPLES_TRUE='#' + BUILD_EXAMPLES_FALSE= +fi + + +# Checks for header files. +# AC_HEADER_STDC +for ac_header in errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in sys/select.h sys/socket.h sys/ioctl.h sys/time.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in arpa/inet.h netinet/in.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in sys/un.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_un_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_UN_H 1 +_ACEOF + have_sys_un_h=yes +else + have_sys_un_h=no +fi + +done + + if test "x$have_sys_un_h" = xyes; then + HAVE_SYS_UN_H_TRUE= + HAVE_SYS_UN_H_FALSE='#' +else + HAVE_SYS_UN_H_TRUE='#' + HAVE_SYS_UN_H_FALSE= +fi + + +case $host in + *-*-cygwin* | *-*-cegcc*) + # These are POSIX-like systems using BSD-like sockets API. + ;; + *) + for ac_header in windows.h winsock2.h ws2tcpip.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + ;; +esac + +case $host in + *darwin*|*interix*) + { $as_echo "$as_me:${as_lineno-$LINENO}: poll use is disabled on this platform" >&5 +$as_echo "$as_me: poll use is disabled on this platform" >&6;} + ;; + *) + for ac_func in poll +do : + ac_fn_c_check_func "$LINENO" "poll" "ac_cv_func_poll" +if test "x$ac_cv_func_poll" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_POLL 1 +_ACEOF + +fi +done + + ;; +esac + +for ac_func in gettimeofday select strtoll +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +if test "$ac_cv_func_select" != "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for select in ws2_32" >&5 +$as_echo_n "checking for select in ws2_32... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_WINSOCK2_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#endif + +int +main () +{ + + select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + HAVE_SELECT="1" + +cat >>confdefs.h <<_ACEOF +#define HAVE_SELECT 1 +_ACEOF + + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if ${ac_cv_working_alloca_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_alloca_h=yes +else + ac_cv_working_alloca_h=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if ${ac_cv_func_alloca_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +void *alloca (size_t); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_alloca_works=yes +else + ac_cv_func_alloca_works=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +$as_echo "#define C_ALLOCA 1" >>confdefs.h + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if ${ac_cv_os_cray+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then : + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if ${ac_cv_c_stack_direction+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_c_stack_direction=0 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction (int *addr, int depth) +{ + int dir, dummy = 0; + if (! addr) + addr = &dummy; + *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; + dir = depth ? find_stack_direction (addr, depth - 1) : 0; + return dir + dummy; +} + +int +main (int argc, char **argv) +{ + return find_stack_direction (0, argc + !argv + 20) < 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$ac_cv_c_stack_direction" >&6; } +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking non-blocking sockets style" >&5 +$as_echo_n "checking non-blocking sockets style... " >&6; } + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* headers for O_NONBLOCK test */ +#include +#include +#include + +int +main () +{ + +/* try to compile O_NONBLOCK */ + +#if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# if defined(__SVR4) || defined(__srv4__) +# define PLATFORM_SOLARIS +# else +# define PLATFORM_SUNOS4 +# endif +#endif +#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41) +# define PLATFORM_AIX_V3 +#endif + +#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__) +#error "O_NONBLOCK does not work on this platform" +#endif + int socket; + int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +nonblock="O_NONBLOCK" + +$as_echo "#define HAVE_O_NONBLOCK 1" >>confdefs.h + + +else + + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* headers for FIONBIO test */ +#include +#include + +int +main () +{ + +/* FIONBIO source test (old-style unix) */ + int socket; + int flags = ioctl(socket, FIONBIO, &flags); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +nonblock="FIONBIO" + +$as_echo "#define HAVE_FIONBIO 1" >>confdefs.h + + +else + + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* headers for ioctlsocket test (Windows) */ +#undef inline +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#ifdef HAVE_WINSOCK2_H +#include +#else +#ifdef HAVE_WINSOCK_H +#include +#endif +#endif +#endif + +int +main () +{ + +/* ioctlsocket source code */ + SOCKET sd; + unsigned long flags = 0; + sd = socket(0, 0, 0); + ioctlsocket(sd, FIONBIO, &flags); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +nonblock="ioctlsocket" + +$as_echo "#define HAVE_IOCTLSOCKET 1" >>confdefs.h + + +else + + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* headers for IoctlSocket test (Amiga?) */ +#include + +int +main () +{ + +/* IoctlSocket source code */ + int socket; + int flags = IoctlSocket(socket, FIONBIO, (long)1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +nonblock="IoctlSocket" + +$as_echo "#define HAVE_IOCTLSOCKET_CASE 1" >>confdefs.h + + +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* headers for SO_NONBLOCK test (BeOS) */ +#include + +int +main () +{ + +/* SO_NONBLOCK source code */ + long b = 1; + int socket; + int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +nonblock="SO_NONBLOCK" + +$as_echo "#define HAVE_SO_NONBLOCK 1" >>confdefs.h + + +else + +nonblock="nada" + +$as_echo "#define HAVE_DISABLED_NONBLOCKING 1" >>confdefs.h + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $nonblock" >&5 +$as_echo "$nonblock" >&6; } + + if test "$nonblock" = "nada"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: non-block sockets disabled" >&5 +$as_echo "$as_me: WARNING: non-block sockets disabled" >&2;} + fi + + +ac_config_files="$ac_config_files Makefile src/Makefile libssh2.pc" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${SSHD_TRUE}" && test -z "${SSHD_FALSE}"; then + as_fn_error $? "conditional \"SSHD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +if test -z "${OPENSSL_TRUE}" && test -z "${OPENSSL_FALSE}"; then + as_fn_error $? "conditional \"OPENSSL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WINCNG_TRUE}" && test -z "${WINCNG_FALSE}"; then + as_fn_error $? "conditional \"WINCNG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LIBGCRYPT_TRUE}" && test -z "${LIBGCRYPT_FALSE}"; then + as_fn_error $? "conditional \"LIBGCRYPT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MBEDTLS_TRUE}" && test -z "${MBEDTLS_FALSE}"; then + as_fn_error $? "conditional \"MBEDTLS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${OS400QC3_TRUE}" && test -z "${OS400QC3_FALSE}"; then + as_fn_error $? "conditional \"OS400QC3\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${BUILD_EXAMPLES_TRUE}" && test -z "${BUILD_EXAMPLES_FALSE}"; then + as_fn_error $? "conditional \"BUILD_EXAMPLES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_SYS_UN_H_TRUE}" && test -z "${HAVE_SYS_UN_H_FALSE}"; then + as_fn_error $? "conditional \"HAVE_SYS_UN_H\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + 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 + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by libssh2 $as_me -, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +libssh2 config.status - +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "src/libssh2_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/libssh2_config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "libssh2.pc") CONFIG_FILES="$CONFIG_FILES libssh2.pc" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# The names of the tagged configurations supported by this script. +available_tags='' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: summary of build options: + + version: ${LIBSSH2VER} + Host type: ${host} + Install prefix: ${prefix} + Compiler: ${CC} + Compiler flags: ${CFLAGS} + Library types: Shared=${enable_shared}, Static=${enable_static} + Crypto library: ${found_crypto} + Clear memory: $enable_clear_memory + Debug build: $enable_debug + Build examples: $build_examples + Path to sshd: $ac_cv_path_SSHD (only for self-tests) + zlib compression: $ac_cv_libz +" >&5 +$as_echo "$as_me: summary of build options: + + version: ${LIBSSH2VER} + Host type: ${host} + Install prefix: ${prefix} + Compiler: ${CC} + Compiler flags: ${CFLAGS} + Library types: Shared=${enable_shared}, Static=${enable_static} + Crypto library: ${found_crypto} + Clear memory: $enable_clear_memory + Debug build: $enable_debug + Build examples: $build_examples + Path to sshd: $ac_cv_path_SSHD (only for self-tests) + zlib compression: $ac_cv_libz +" >&6;} diff --git a/libssh2/configure.ac b/libssh2/configure.ac new file mode 100644 index 000000000..72ee735bf --- /dev/null +++ b/libssh2/configure.ac @@ -0,0 +1,373 @@ +# AC_PREREQ(2.57) +AC_INIT(libssh2, [-], libssh2-devel@cool.haxx.se) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_SRCDIR([src]) +AC_CONFIG_HEADERS([src/libssh2_config.h]) +AM_MAINTAINER_MODE +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +dnl SED is needed by some of the tools +AC_PATH_PROG( SED, sed, sed-was-not-found-by-configure, + $PATH:/usr/bin:/usr/local/bin) +AC_SUBST(SED) + +if test "x$SED" = "xsed-was-not-found-by-configure"; then + AC_MSG_WARN([sed was not found, this may ruin your chances to build fine]) +fi + +dnl figure out the libssh2 version +LIBSSH2VER=`$SED -ne 's/^#define LIBSSH2_VERSION *"\(.*\)"/\1/p' ${srcdir}/include/libssh2.h` +AM_INIT_AUTOMAKE +AC_MSG_CHECKING([libssh2 version]) +AC_MSG_RESULT($LIBSSH2VER) + +AC_SUBST(LIBSSH2VER) + +AB_VERSION=$LIBSSH2VER + +AB_INIT + +# Check for the OS. +# Daniel's note: this should not be necessary and we need to work to +# get this removed. +AC_CANONICAL_HOST +case "$host" in + *-mingw*) + CFLAGS="$CFLAGS -DLIBSSH2_WIN32" + LIBS="$LIBS -lws2_32" + ;; + *-cygwin) + CFLAGS="$CFLAGS -DLIBSSH2_WIN32" + ;; + *darwin*) + CFLAGS="$CFLAGS -DLIBSSH2_DARWIN" + ;; + *hpux*) + ;; + *osf*) + CFLAGS="$CFLAGS -D_POSIX_PII_SOCKET" + ;; + *) + ;; +esac + +AC_CHECK_TYPE(long long, + [AC_DEFINE(HAVE_LONGLONG, 1, + [Define to 1 if the compiler supports the 'long long' data type.])] + longlong="yes" +) + +dnl Our configure and build reentrant settings +CURL_CONFIGURE_REENTRANT + +# Some systems (Solaris?) have socket() in -lsocket. +AC_SEARCH_LIBS(socket, socket) + +# Solaris has inet_addr() in -lnsl. +AC_SEARCH_LIBS(inet_addr, nsl) + +AC_SUBST(LIBS) + +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +AC_PATH_PROGS(SSHD, [sshd], [], + [$PATH$PATH_SEPARATOR/usr/libexec$PATH_SEPARATOR]dnl + [/usr/sbin$PATH_SEPARATOR/usr/etc$PATH_SEPARATOR/etc]) +AM_CONDITIONAL(SSHD, test -n "$SSHD") +AC_LIBTOOL_WIN32_DLL +AC_PROG_LIBTOOL +AC_C_BIGENDIAN + +dnl check for how to do large files +AC_SYS_LARGEFILE + +found_crypto=none + +# Configure parameters +AC_ARG_WITH(openssl, + AC_HELP_STRING([--with-openssl],[Use OpenSSL for crypto]), + use_openssl=$withval,use_openssl=auto) +AC_ARG_WITH(libgcrypt, + AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]), + [ use_libgcrypt=$withval + LIBSSH2_CHECKFOR_GCRYPT + ], use_libgcrypt=auto) +AC_ARG_WITH(wincng, + AC_HELP_STRING([--with-wincng],[Use Windows CNG for crypto]), + [ use_wincng=$withval + LIBSSH2_CHECKFOR_WINCNG + ] ,use_wincng=auto) +AC_ARG_WITH([mbedtls], + AC_HELP_STRING([--with-mbedtls],[Use mbedTLS for crypto]), + [ use_mbedtls=$withval + LIBSSH2_CHECKFOR_MBEDTLS + ], use_mbedtls=auto +) +AC_ARG_WITH(libz, + AC_HELP_STRING([--with-libz],[Use zlib for compression]), + use_libz=$withval,use_libz=auto) + +support_clear_memory=no + +# Look for OpenSSL +if test "$found_crypto" = "none" && test "$use_openssl" != "no"; then + AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include ]) +fi +if test "$ac_cv_libssl" = "yes"; then + AC_DEFINE(LIBSSH2_OPENSSL, 1, [Use OpenSSL]) + LIBSREQUIRED=libssl,libcrypto + + # Not all OpenSSL have AES-CTR functions. + save_LIBS="$LIBS" + LIBS="$LIBS $LIBSSL" + AC_CHECK_FUNCS(EVP_aes_128_ctr) + LIBS="$save_LIBS" + + found_crypto="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})" +fi + +AM_CONDITIONAL(OPENSSL, test "$ac_cv_libssl" = "yes") +AM_CONDITIONAL(WINCNG, test "$ac_cv_libbcrypt" = "yes") +AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes") +AM_CONDITIONAL(MBEDTLS, test "$ac_cv_libmbedtls" = "yes") +AM_CONDITIONAL(OS400QC3, false) + +# Check if crypto library was found +if test "$found_crypto" = "none"; then + AC_MSG_ERROR([No crypto library found! +Try --with-libssl-prefix=PATH + or --with-libgcrypt-prefix=PATH + or --with-libmbedtls-prefix=PATH + or --with-wincng on Windows\ +]) +fi + +# Look for Libz +if test "$use_libz" != "no"; then + AC_LIB_HAVE_LINKFLAGS([z], [], [#include ]) + if test "$ac_cv_libz" != yes; then + AC_MSG_NOTICE([Cannot find zlib, disabling compression]) + AC_MSG_NOTICE([Try --with-libz-prefix=PATH if you know you have it]) + else + AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support]) + if test "${LIBSREQUIRED}" != ""; then + LIBSREQUIRED="${LIBSREQUIRED}," + fi + LIBSREQUIRED="${LIBSREQUIRED}zlib" + fi +fi + +AC_SUBST(LIBSREQUIRED) + +# +# Optional Settings +# +AC_ARG_ENABLE(crypt-none, + AC_HELP_STRING([--enable-crypt-none],[Permit "none" cipher -- NOT RECOMMENDED]), + [AC_DEFINE(LIBSSH2_CRYPT_NONE, 1, [Enable "none" cipher -- NOT RECOMMENDED])]) + +AC_ARG_ENABLE(mac-none, + AC_HELP_STRING([--enable-mac-none],[Permit "none" MAC -- NOT RECOMMENDED]), + [AC_DEFINE(LIBSSH2_MAC_NONE, 1, [Enable "none" MAC -- NOT RECOMMENDED])]) + +AC_ARG_ENABLE(gex-new, + AC_HELP_STRING([--disable-gex-new],[Disable "new" diffie-hellman-group-exchange-sha1 method]), + [GEX_NEW=$enableval]) +if test "$GEX_NEW" != "no"; then + AC_DEFINE(LIBSSH2_DH_GEX_NEW, 1, [Enable newer diffie-hellman-group-exchange-sha1 syntax]) +fi + +AC_ARG_ENABLE(clear-memory, + AC_HELP_STRING([--disable-clear-memory],[Disable clearing of memory before being freed]), + [CLEAR_MEMORY=$enableval]) +if test "$CLEAR_MEMORY" != "no"; then + if test "$support_clear_memory" = "yes"; then + AC_DEFINE(LIBSSH2_CLEAR_MEMORY, 1, [Enable clearing of memory before being freed]) + enable_clear_memory=yes + else + if test "$CLEAR_MEMORY" = "yes"; then + AC_MSG_ERROR([secure clearing/zeroing of memory is not supported by the selected crypto backend]) + else + AC_MSG_WARN([secure clearing/zeroing of memory is not supported by the selected crypto backend]) + fi + enable_clear_memory=unsupported + fi +else + if test "$support_clear_memory" = "yes"; then + enable_clear_memory=no + else + AC_MSG_WARN([secure clearing/zeroing of memory is not supported by the selected crypto backend]) + enable_clear_memory=unsupported + fi +fi + +dnl ************************************************************ +dnl option to switch on compiler debug options +dnl +AC_MSG_CHECKING([whether to enable pedantic and debug compiler options]) +AC_ARG_ENABLE(debug, +AC_HELP_STRING([--enable-debug],[Enable pedantic and debug options]) +AC_HELP_STRING([--disable-debug],[Disable debug options]), +[ case "$enable_debug" in + no) + AC_MSG_RESULT(no) + ;; + *) AC_MSG_RESULT(yes) + enable_debug=yes + CPPFLAGS="$CPPFLAGS -DLIBSSH2DEBUG" + CFLAGS="$CFLAGS -g" + + dnl set compiler "debug" options to become more picky, and remove + dnl optimize options from CFLAGS + CURL_CC_DEBUG_OPTS + ;; + esac + ], + enable_debug=no + AC_MSG_RESULT(no) +) + +dnl ************************************************************ +dnl Enable hiding of internal symbols in library to reduce its size and +dnl speed dynamic linking of applications. This currently is only supported +dnl on gcc >= 4.0 and SunPro C. +dnl +AC_MSG_CHECKING([whether to enable hidden symbols in the library]) +AC_ARG_ENABLE(hidden-symbols, +AC_HELP_STRING([--enable-hidden-symbols],[Hide internal symbols in library]) +AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibility in library]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + ;; + *) + AC_MSG_CHECKING([whether $CC supports it]) + if test "$GCC" = yes ; then + if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then + AC_MSG_RESULT(yes) + AC_DEFINE(LIBSSH2_API, [__attribute__ ((visibility ("default")))], [to make a symbol visible]) + CFLAGS="$CFLAGS -fvisibility=hidden" + else + AC_MSG_RESULT(no) + fi + + else + dnl Test for SunPro cc + if $CC 2>&1 | grep flags >/dev/null && $CC -flags | grep xldscope= >/dev/null ; then + AC_MSG_RESULT(yes) + AC_DEFINE(LIBSSH2_API, [__global], [to make a symbol visible]) + CFLAGS="$CFLAGS -xldscope=hidden" + else + AC_MSG_RESULT(no) + fi + fi + ;; + esac ], + AC_MSG_RESULT(no) +) + +# Build example applications? +AC_MSG_CHECKING([whether to build example applications]) +AC_ARG_ENABLE([examples-build], +AC_HELP_STRING([--enable-examples-build], [Build example applications (this is the default)]) +AC_HELP_STRING([--disable-examples-build], [Do not build example applications]), +[case "$enableval" in + no | false) + build_examples='no' + ;; + *) + build_examples='yes' + ;; +esac], [build_examples='yes']) +AC_MSG_RESULT($build_examples) +AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"]) + +# Checks for header files. +# AC_HEADER_STDC +AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h]) +AC_CHECK_HEADERS([sys/select.h sys/socket.h sys/ioctl.h sys/time.h]) +AC_CHECK_HEADERS([arpa/inet.h netinet/in.h]) +AC_CHECK_HEADERS([sys/un.h], [have_sys_un_h=yes], [have_sys_un_h=no]) +AM_CONDITIONAL([HAVE_SYS_UN_H], test "x$have_sys_un_h" = xyes) + +case $host in + *-*-cygwin* | *-*-cegcc*) + # These are POSIX-like systems using BSD-like sockets API. + ;; + *) + AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h]) + ;; +esac + +case $host in + *darwin*|*interix*) + dnl poll() does not work on these platforms + dnl Interix: "does provide poll(), but the implementing developer must + dnl have been in a bad mood, because poll() only works on the /proc + dnl filesystem here" + dnl Mac OS X's poll has funny behaviors, like: + dnl not being able to do poll on no fildescriptors (10.3?) + dnl not being able to poll on some files (like anything in /dev) + dnl not having reliable timeout support + dnl inconsistent return of POLLHUP where other implementations give POLLIN + AC_MSG_NOTICE([poll use is disabled on this platform]) + ;; + *) + AC_CHECK_FUNCS(poll) + ;; +esac + +AC_CHECK_FUNCS(gettimeofday select strtoll) + +dnl Check for select() into ws2_32 for Msys/Mingw +if test "$ac_cv_func_select" != "yes"; then + AC_MSG_CHECKING([for select in ws2_32]) + AC_TRY_LINK([ +#ifdef HAVE_WINSOCK2_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#endif + ],[ + select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL); + ],[ + AC_MSG_RESULT([yes]) + HAVE_SELECT="1" + AC_DEFINE_UNQUOTED(HAVE_SELECT, 1, + [Define to 1 if you have the select function.]) + ],[ + AC_MSG_RESULT([no]) + ]) +fi + +AC_FUNC_ALLOCA + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE + +CURL_CHECK_NONBLOCKING_SOCKET + +AC_CONFIG_FILES([Makefile + src/Makefile + libssh2.pc]) +AC_OUTPUT + +AC_MSG_NOTICE([summary of build options: + + version: ${LIBSSH2VER} + Host type: ${host} + Install prefix: ${prefix} + Compiler: ${CC} + Compiler flags: ${CFLAGS} + Library types: Shared=${enable_shared}, Static=${enable_static} + Crypto library: ${found_crypto} + Clear memory: $enable_clear_memory + Debug build: $enable_debug + Build examples: $build_examples + Path to sshd: $ac_cv_path_SSHD (only for self-tests) + zlib compression: $ac_cv_libz +]) diff --git a/libssh2/depcomp b/libssh2/depcomp new file mode 100644 index 000000000..fc98710e2 --- /dev/null +++ b/libssh2/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2013-05-30.07; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libssh2/get_ver.awk b/libssh2/get_ver.awk new file mode 100644 index 000000000..8253168e6 --- /dev/null +++ b/libssh2/get_ver.awk @@ -0,0 +1,24 @@ +# fetch libssh2 version number from input file and write them to STDOUT +BEGIN { + while ((getline < ARGV[1]) > 0) { + if (match ($0, /^#define LIBSSH2_COPYRIGHT "[^"]+"$/)) { + my_copyright_str = substr($0, 28, length($0)-28); + } + else if (match ($0, /^#define LIBSSH2_VERSION[ |\t]+"[^"]+"/)) { + my_ver_str = substr($3, 2, length($3) - 2); + split(my_ver_str, v, "."); + if (v[3]) + gsub("[^0-9].*$", "", v[3]); + else + v[3] = 0; + if (v[2]) + gsub("[^0-9].*$", "", v[2]); + else + v[2] = 0; + my_ver = v[1] "," v[2] "," v[3]; + } + } + print "LIBSSH2_VERSION = " my_ver ""; + print "LIBSSH2_VERSION_STR = " my_ver_str ""; + print "LIBSSH2_COPYRIGHT_STR = " my_copyright_str ""; +} diff --git a/libssh2/include/libssh2.h b/libssh2/include/libssh2.h new file mode 100644 index 000000000..34d284210 --- /dev/null +++ b/libssh2/include/libssh2.h @@ -0,0 +1,1294 @@ +/* Copyright (c) 2004-2009, Sara Golemon + * Copyright (c) 2009-2015 Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBSSH2_H +#define LIBSSH2_H 1 + +#define LIBSSH2_COPYRIGHT "2004-2016 The libssh2 project and its contributors." + +/* We use underscore instead of dash when appending DEV in dev versions just + to make the BANNER define (used by src/session.c) be a valid SSH + banner. Release versions have no appended strings and may of course not + have dashes either. */ +#define LIBSSH2_VERSION "1.8.0" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBSSH2_VERSION_MAJOR 1 +#define LIBSSH2_VERSION_MINOR 8 +#define LIBSSH2_VERSION_PATCH 0 + +/* This is the numeric version of the libssh2 version number, meant for easier + parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. +*/ +#define LIBSSH2_VERSION_NUM 0x010800 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in the source code repo, as the timestamp is + * properly set in the tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBSSH2_TIMESTAMP "Tue Oct 25 06:44:33 UTC 2016" + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _WIN32 +# include +# include +#endif + +#include +#include +#include +#include + +/* Allow alternate API prefix from CFLAGS or calling app */ +#ifndef LIBSSH2_API +# ifdef LIBSSH2_WIN32 +# ifdef _WINDLL +# ifdef LIBSSH2_LIBRARY +# define LIBSSH2_API __declspec(dllexport) +# else +# define LIBSSH2_API __declspec(dllimport) +# endif /* LIBSSH2_LIBRARY */ +# else +# define LIBSSH2_API +# endif +# else /* !LIBSSH2_WIN32 */ +# define LIBSSH2_API +# endif /* LIBSSH2_WIN32 */ +#endif /* LIBSSH2_API */ + +#ifdef HAVE_SYS_UIO_H +# include +#endif + +#if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) +# include +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +#endif + +#ifdef _MSC_VER +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 libssh2_uint64_t; +typedef __int64 libssh2_int64_t; +#ifndef ssize_t +typedef SSIZE_T ssize_t; +#endif +#else +typedef unsigned long long libssh2_uint64_t; +typedef long long libssh2_int64_t; +#endif + +#ifdef WIN32 +typedef SOCKET libssh2_socket_t; +#define LIBSSH2_INVALID_SOCKET INVALID_SOCKET +#else /* !WIN32 */ +typedef int libssh2_socket_t; +#define LIBSSH2_INVALID_SOCKET -1 +#endif /* WIN32 */ + +/* + * Determine whether there is small or large file support on windows. + */ + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define LIBSSH2_USE_WIN32_LARGE_FILES +# else +# define LIBSSH2_USE_WIN32_SMALL_FILES +# endif +#endif + +#if defined(__MINGW32__) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) +# define LIBSSH2_USE_WIN32_LARGE_FILES +#endif + +#if defined(__WATCOMC__) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) +# define LIBSSH2_USE_WIN32_LARGE_FILES +#endif + +#if defined(__POCC__) +# undef LIBSSH2_USE_WIN32_LARGE_FILES +#endif + +#if defined(_WIN32) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) && \ + !defined(LIBSSH2_USE_WIN32_SMALL_FILES) +# define LIBSSH2_USE_WIN32_SMALL_FILES +#endif + +/* + * Large file (>2Gb) support using WIN32 functions. + */ + +#ifdef LIBSSH2_USE_WIN32_LARGE_FILES +# include +# include +# include +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%I64d" +typedef struct _stati64 libssh2_struct_stat; +typedef __int64 libssh2_struct_stat_size; +#endif + +/* + * Small file (<2Gb) support using WIN32 functions. + */ + +#ifdef LIBSSH2_USE_WIN32_SMALL_FILES +# include +# include +# ifndef _WIN32_WCE +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%d" +typedef struct _stat libssh2_struct_stat; +typedef off_t libssh2_struct_stat_size; +# endif +#endif + +#ifndef LIBSSH2_STRUCT_STAT_SIZE_FORMAT +# ifdef __VMS +/* We have to roll our own format here because %z is a C99-ism we don't have. */ +# if __USE_OFF64_T || __USING_STD_STAT +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%Ld" +# else +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%d" +# endif +# else +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%zd" +# endif +typedef struct stat libssh2_struct_stat; +typedef off_t libssh2_struct_stat_size; +#endif + +/* Part of every banner, user specified or not */ +#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION + +/* We *could* add a comment here if we so chose */ +#define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER +#define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n" + +/* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 */ +#define LIBSSH2_DH_GEX_MINGROUP 1024 +#define LIBSSH2_DH_GEX_OPTGROUP 1536 +#define LIBSSH2_DH_GEX_MAXGROUP 2048 + +/* Defaults for pty requests */ +#define LIBSSH2_TERM_WIDTH 80 +#define LIBSSH2_TERM_HEIGHT 24 +#define LIBSSH2_TERM_WIDTH_PX 0 +#define LIBSSH2_TERM_HEIGHT_PX 0 + +/* 1/4 second */ +#define LIBSSH2_SOCKET_POLL_UDELAY 250000 +/* 0.25 * 120 == 30 seconds */ +#define LIBSSH2_SOCKET_POLL_MAXLOOPS 120 + +/* Maximum size to allow a payload to compress to, plays it safe by falling + short of spec limits */ +#define LIBSSH2_PACKET_MAXCOMP 32000 + +/* Maximum size to allow a payload to deccompress to, plays it safe by + allowing more than spec requires */ +#define LIBSSH2_PACKET_MAXDECOMP 40000 + +/* Maximum size for an inbound compressed payload, plays it safe by + overshooting spec limits */ +#define LIBSSH2_PACKET_MAXPAYLOAD 40000 + +/* Malloc callbacks */ +#define LIBSSH2_ALLOC_FUNC(name) void *name(size_t count, void **abstract) +#define LIBSSH2_REALLOC_FUNC(name) void *name(void *ptr, size_t count, \ + void **abstract) +#define LIBSSH2_FREE_FUNC(name) void name(void *ptr, void **abstract) + +typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT +{ + char* text; + unsigned int length; + unsigned char echo; +} LIBSSH2_USERAUTH_KBDINT_PROMPT; + +typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE +{ + char* text; + unsigned int length; +} LIBSSH2_USERAUTH_KBDINT_RESPONSE; + +/* 'publickey' authentication callback */ +#define LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC(name) \ + int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, \ + const unsigned char *data, size_t data_len, void **abstract) + +/* 'keyboard-interactive' authentication callback */ +#define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) \ + void name_(const char* name, int name_len, const char* instruction, \ + int instruction_len, int num_prompts, \ + const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, \ + LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract) + +/* Callbacks for special SSH packets */ +#define LIBSSH2_IGNORE_FUNC(name) \ + void name(LIBSSH2_SESSION *session, const char *message, int message_len, \ + void **abstract) + +#define LIBSSH2_DEBUG_FUNC(name) \ + void name(LIBSSH2_SESSION *session, int always_display, const char *message, \ + int message_len, const char *language, int language_len, \ + void **abstract) + +#define LIBSSH2_DISCONNECT_FUNC(name) \ + void name(LIBSSH2_SESSION *session, int reason, const char *message, \ + int message_len, const char *language, int language_len, \ + void **abstract) + +#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) \ + void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, \ + void **abstract) + +#define LIBSSH2_MACERROR_FUNC(name) \ + int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, \ + void **abstract) + +#define LIBSSH2_X11_OPEN_FUNC(name) \ + void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, \ + const char *shost, int sport, void **abstract) + +#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) \ + void name(LIBSSH2_SESSION *session, void **session_abstract, \ + LIBSSH2_CHANNEL *channel, void **channel_abstract) + +/* I/O callbacks */ +#define LIBSSH2_RECV_FUNC(name) ssize_t name(libssh2_socket_t socket, \ + void *buffer, size_t length, \ + int flags, void **abstract) +#define LIBSSH2_SEND_FUNC(name) ssize_t name(libssh2_socket_t socket, \ + const void *buffer, size_t length,\ + int flags, void **abstract) + +/* libssh2_session_callback_set() constants */ +#define LIBSSH2_CALLBACK_IGNORE 0 +#define LIBSSH2_CALLBACK_DEBUG 1 +#define LIBSSH2_CALLBACK_DISCONNECT 2 +#define LIBSSH2_CALLBACK_MACERROR 3 +#define LIBSSH2_CALLBACK_X11 4 +#define LIBSSH2_CALLBACK_SEND 5 +#define LIBSSH2_CALLBACK_RECV 6 + +/* libssh2_session_method_pref() constants */ +#define LIBSSH2_METHOD_KEX 0 +#define LIBSSH2_METHOD_HOSTKEY 1 +#define LIBSSH2_METHOD_CRYPT_CS 2 +#define LIBSSH2_METHOD_CRYPT_SC 3 +#define LIBSSH2_METHOD_MAC_CS 4 +#define LIBSSH2_METHOD_MAC_SC 5 +#define LIBSSH2_METHOD_COMP_CS 6 +#define LIBSSH2_METHOD_COMP_SC 7 +#define LIBSSH2_METHOD_LANG_CS 8 +#define LIBSSH2_METHOD_LANG_SC 9 + +/* flags */ +#define LIBSSH2_FLAG_SIGPIPE 1 +#define LIBSSH2_FLAG_COMPRESS 2 + +typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; +typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; +typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER; +typedef struct _LIBSSH2_KNOWNHOSTS LIBSSH2_KNOWNHOSTS; +typedef struct _LIBSSH2_AGENT LIBSSH2_AGENT; + +typedef struct _LIBSSH2_POLLFD { + unsigned char type; /* LIBSSH2_POLLFD_* below */ + + union { + libssh2_socket_t socket; /* File descriptors -- examined with + system select() call */ + LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */ + LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound + connections waiting to be accepted? */ + } fd; + + unsigned long events; /* Requested Events */ + unsigned long revents; /* Returned Events */ +} LIBSSH2_POLLFD; + +/* Poll FD Descriptor Types */ +#define LIBSSH2_POLLFD_SOCKET 1 +#define LIBSSH2_POLLFD_CHANNEL 2 +#define LIBSSH2_POLLFD_LISTENER 3 + +/* Note: Win32 Doesn't actually have a poll() implementation, so some of these + values are faked with select() data */ +/* Poll FD events/revents -- Match sys/poll.h where possible */ +#define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or + connection available -- + All */ +#define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to + be read -- Socket only */ +#define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to + be read -- Channel only */ +#define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written -- + Socket/Channel */ +/* revents only */ +#define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */ +#define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket */ +#define LIBSSH2_POLLFD_SESSION_CLOSED 0x0010 /* Session Disconnect */ +#define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket + Only */ +#define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition -- + Socket/Win32 */ +#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */ +#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */ + +#define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION +/* Block Direction Types */ +#define LIBSSH2_SESSION_BLOCK_INBOUND 0x0001 +#define LIBSSH2_SESSION_BLOCK_OUTBOUND 0x0002 + +/* Hash Types */ +#define LIBSSH2_HOSTKEY_HASH_MD5 1 +#define LIBSSH2_HOSTKEY_HASH_SHA1 2 + +/* Hostkey Types */ +#define LIBSSH2_HOSTKEY_TYPE_UNKNOWN 0 +#define LIBSSH2_HOSTKEY_TYPE_RSA 1 +#define LIBSSH2_HOSTKEY_TYPE_DSS 2 + +/* Disconnect Codes (defined by SSH protocol) */ +#define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 +#define SSH_DISCONNECT_PROTOCOL_ERROR 2 +#define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3 +#define SSH_DISCONNECT_RESERVED 4 +#define SSH_DISCONNECT_MAC_ERROR 5 +#define SSH_DISCONNECT_COMPRESSION_ERROR 6 +#define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7 +#define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 +#define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 +#define SSH_DISCONNECT_CONNECTION_LOST 10 +#define SSH_DISCONNECT_BY_APPLICATION 11 +#define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12 +#define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13 +#define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 +#define SSH_DISCONNECT_ILLEGAL_USER_NAME 15 + +/* Error Codes (defined by libssh2) */ +#define LIBSSH2_ERROR_NONE 0 + +/* The library once used -1 as a generic error return value on numerous places + through the code, which subsequently was converted to + LIBSSH2_ERROR_SOCKET_NONE uses over time. As this is a generic error code, + the goal is to never ever return this code but instead make sure that a + more accurate and descriptive error code is used. */ +#define LIBSSH2_ERROR_SOCKET_NONE -1 + +#define LIBSSH2_ERROR_BANNER_RECV -2 +#define LIBSSH2_ERROR_BANNER_SEND -3 +#define LIBSSH2_ERROR_INVALID_MAC -4 +#define LIBSSH2_ERROR_KEX_FAILURE -5 +#define LIBSSH2_ERROR_ALLOC -6 +#define LIBSSH2_ERROR_SOCKET_SEND -7 +#define LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE -8 +#define LIBSSH2_ERROR_TIMEOUT -9 +#define LIBSSH2_ERROR_HOSTKEY_INIT -10 +#define LIBSSH2_ERROR_HOSTKEY_SIGN -11 +#define LIBSSH2_ERROR_DECRYPT -12 +#define LIBSSH2_ERROR_SOCKET_DISCONNECT -13 +#define LIBSSH2_ERROR_PROTO -14 +#define LIBSSH2_ERROR_PASSWORD_EXPIRED -15 +#define LIBSSH2_ERROR_FILE -16 +#define LIBSSH2_ERROR_METHOD_NONE -17 +#define LIBSSH2_ERROR_AUTHENTICATION_FAILED -18 +#define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED LIBSSH2_ERROR_AUTHENTICATION_FAILED +#define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED -19 +#define LIBSSH2_ERROR_CHANNEL_OUTOFORDER -20 +#define LIBSSH2_ERROR_CHANNEL_FAILURE -21 +#define LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED -22 +#define LIBSSH2_ERROR_CHANNEL_UNKNOWN -23 +#define LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED -24 +#define LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED -25 +#define LIBSSH2_ERROR_CHANNEL_CLOSED -26 +#define LIBSSH2_ERROR_CHANNEL_EOF_SENT -27 +#define LIBSSH2_ERROR_SCP_PROTOCOL -28 +#define LIBSSH2_ERROR_ZLIB -29 +#define LIBSSH2_ERROR_SOCKET_TIMEOUT -30 +#define LIBSSH2_ERROR_SFTP_PROTOCOL -31 +#define LIBSSH2_ERROR_REQUEST_DENIED -32 +#define LIBSSH2_ERROR_METHOD_NOT_SUPPORTED -33 +#define LIBSSH2_ERROR_INVAL -34 +#define LIBSSH2_ERROR_INVALID_POLL_TYPE -35 +#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36 +#define LIBSSH2_ERROR_EAGAIN -37 +#define LIBSSH2_ERROR_BUFFER_TOO_SMALL -38 +#define LIBSSH2_ERROR_BAD_USE -39 +#define LIBSSH2_ERROR_COMPRESS -40 +#define LIBSSH2_ERROR_OUT_OF_BOUNDARY -41 +#define LIBSSH2_ERROR_AGENT_PROTOCOL -42 +#define LIBSSH2_ERROR_SOCKET_RECV -43 +#define LIBSSH2_ERROR_ENCRYPT -44 +#define LIBSSH2_ERROR_BAD_SOCKET -45 +#define LIBSSH2_ERROR_KNOWN_HOSTS -46 + +/* this is a define to provide the old (<= 1.2.7) name */ +#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV + +/* Global API */ +#define LIBSSH2_INIT_NO_CRYPTO 0x0001 + +/* + * libssh2_init() + * + * Initialize the libssh2 functions. This typically initialize the + * crypto library. It uses a global state, and is not thread safe -- + * you must make sure this function is not called concurrently. + * + * Flags can be: + * 0: Normal initialize + * LIBSSH2_INIT_NO_CRYPTO: Do not initialize the crypto library (ie. + * OPENSSL_add_cipher_algoritms() for OpenSSL + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int libssh2_init(int flags); + +/* + * libssh2_exit() + * + * Exit the libssh2 functions and free's all memory used internal. + */ +LIBSSH2_API void libssh2_exit(void); + +/* + * libssh2_free() + * + * Deallocate memory allocated by earlier call to libssh2 functions. + */ +LIBSSH2_API void libssh2_free(LIBSSH2_SESSION *session, void *ptr); + +/* + * libssh2_session_supported_algs() + * + * Fills algs with a list of supported acryptographic algorithms. Returns a + * non-negative number (number of supported algorithms) on success or a + * negative number (an eror code) on failure. + * + * NOTE: on success, algs must be deallocated (by calling libssh2_free) when + * not needed anymore + */ +LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session, + int method_type, + const char*** algs); + +/* Session API */ +LIBSSH2_API LIBSSH2_SESSION * +libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), + LIBSSH2_FREE_FUNC((*my_free)), + LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract); +#define libssh2_session_init() libssh2_session_init_ex(NULL, NULL, NULL, NULL) + +LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session); + +LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session, + int cbtype, void *callback); +LIBSSH2_API int libssh2_session_banner_set(LIBSSH2_SESSION *session, + const char *banner); +LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, + const char *banner); + +LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int sock); +LIBSSH2_API int libssh2_session_handshake(LIBSSH2_SESSION *session, + libssh2_socket_t sock); +LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, + int reason, + const char *description, + const char *lang); +#define libssh2_session_disconnect(session, description) \ + libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, \ + (description), "") + +LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session); + +LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, + int hash_type); + +LIBSSH2_API const char *libssh2_session_hostkey(LIBSSH2_SESSION *session, + size_t *len, int *type); + +LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, + int method_type, + const char *prefs); +LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, + int method_type); +LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, + char **errmsg, + int *errmsg_len, int want_buf); +LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session); +LIBSSH2_API int libssh2_session_set_last_error(LIBSSH2_SESSION* session, + int errcode, + const char* errmsg); +LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session); + +LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, + int value); +LIBSSH2_API const char *libssh2_session_banner_get(LIBSSH2_SESSION *session); + +/* Userauth API */ +LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len); +LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session); + +LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const char *password, + unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))); + +#define libssh2_userauth_password(session, username, password) \ + libssh2_userauth_password_ex((session), (username), \ + (unsigned int)strlen(username), \ + (password), (unsigned int)strlen(password), NULL) + +LIBSSH2_API int +libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const char *publickey, + const char *privatekey, + const char *passphrase); + +#define libssh2_userauth_publickey_fromfile(session, username, publickey, \ + privatekey, passphrase) \ + libssh2_userauth_publickey_fromfile_ex((session), (username), \ + (unsigned int)strlen(username), \ + (publickey), \ + (privatekey), (passphrase)) + +LIBSSH2_API int +libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *username, + const unsigned char *pubkeydata, + size_t pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), + void **abstract); + +LIBSSH2_API int +libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const char *publickey, + const char *privatekey, + const char *passphrase, + const char *hostname, + unsigned int hostname_len, + const char *local_username, + unsigned int local_username_len); + +#define libssh2_userauth_hostbased_fromfile(session, username, publickey, \ + privatekey, passphrase, hostname) \ + libssh2_userauth_hostbased_fromfile_ex((session), (username), \ + (unsigned int)strlen(username), \ + (publickey), \ + (privatekey), (passphrase), \ + (hostname), \ + (unsigned int)strlen(hostname), \ + (username), \ + (unsigned int)strlen(username)) + +LIBSSH2_API int +libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, + const char *username, + size_t username_len, + const char *publickeyfiledata, + size_t publickeyfiledata_len, + const char *privatekeyfiledata, + size_t privatekeyfiledata_len, + const char *passphrase); + +/* + * response_callback is provided with filled by library prompts array, + * but client must allocate and fill individual responses. Responses + * array is already allocated. Responses data will be freed by libssh2 + * after callback return, but before subsequent callback invokation. + */ +LIBSSH2_API int +libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session, + const char *username, + unsigned int username_len, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC( + (*response_callback))); + +#define libssh2_userauth_keyboard_interactive(session, username, \ + response_callback) \ + libssh2_userauth_keyboard_interactive_ex((session), (username), \ + (unsigned int)strlen(username), \ + (response_callback)) + +LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, + long timeout); + +/* Channel API */ +#define LIBSSH2_CHANNEL_WINDOW_DEFAULT (2*1024*1024) +#define LIBSSH2_CHANNEL_PACKET_DEFAULT 32768 +#define LIBSSH2_CHANNEL_MINADJUST 1024 + +/* Extended Data Handling */ +#define LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL 0 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE 1 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE 2 + +#define SSH_EXTENDED_DATA_STDERR 1 + +/* Returned by any function that would block during a read/write opperation */ +#define LIBSSH2CHANNEL_EAGAIN LIBSSH2_ERROR_EAGAIN + +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, + unsigned int channel_type_len, + unsigned int window_size, unsigned int packet_size, + const char *message, unsigned int message_len); + +#define libssh2_channel_open_session(session) \ + libssh2_channel_open_ex((session), "session", sizeof("session") - 1, \ + LIBSSH2_CHANNEL_WINDOW_DEFAULT, \ + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0) + +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, + int port, const char *shost, int sport); +#define libssh2_channel_direct_tcpip(session, host, port) \ + libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22) + +LIBSSH2_API LIBSSH2_LISTENER * +libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, + int port, int *bound_port, int queue_maxsize); +#define libssh2_channel_forward_listen(session, port) \ + libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16) + +LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); + +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener); + +LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, + const char *varname, + unsigned int varname_len, + const char *value, + unsigned int value_len); + +#define libssh2_channel_setenv(channel, varname, value) \ + libssh2_channel_setenv_ex((channel), (varname), \ + (unsigned int)strlen(varname), (value), \ + (unsigned int)strlen(value)) + +LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, + const char *term, + unsigned int term_len, + const char *modes, + unsigned int modes_len, + int width, int height, + int width_px, int height_px); +#define libssh2_channel_request_pty(channel, term) \ + libssh2_channel_request_pty_ex((channel), (term), \ + (unsigned int)strlen(term), \ + NULL, 0, \ + LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, \ + LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX) + +LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, + int width, int height, + int width_px, + int height_px); +#define libssh2_channel_request_pty_size(channel, width, height) \ + libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0) + +LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, + int single_connection, + const char *auth_proto, + const char *auth_cookie, + int screen_number); +#define libssh2_channel_x11_req(channel, screen_number) \ + libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number)) + +LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *request, + unsigned int request_len, + const char *message, + unsigned int message_len); +#define libssh2_channel_shell(channel) \ + libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, \ + NULL, 0) +#define libssh2_channel_exec(channel, command) \ + libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \ + (command), (unsigned int)strlen(command)) +#define libssh2_channel_subsystem(channel, subsystem) \ + libssh2_channel_process_startup((channel), "subsystem", \ + sizeof("subsystem") - 1, (subsystem), \ + (unsigned int)strlen(subsystem)) + +LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, + int stream_id, char *buf, + size_t buflen); +#define libssh2_channel_read(channel, buf, buflen) \ + libssh2_channel_read_ex((channel), 0, (buf), (buflen)) +#define libssh2_channel_read_stderr(channel, buf, buflen) \ + libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) + +LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, + int extended); + +LIBSSH2_API unsigned long +libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, + unsigned long *read_avail, + unsigned long *window_size_initial); +#define libssh2_channel_window_read(channel) \ + libssh2_channel_window_read_ex((channel), NULL, NULL) + +/* libssh2_channel_receive_window_adjust is DEPRECATED, do not use! */ +LIBSSH2_API unsigned long +libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, + unsigned long adjustment, + unsigned char force); + +LIBSSH2_API int +libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel, + unsigned long adjustment, + unsigned char force, + unsigned int *storewindow); + +LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, + int stream_id, const char *buf, + size_t buflen); + +#define libssh2_channel_write(channel, buf, buflen) \ + libssh2_channel_write_ex((channel), 0, (buf), (buflen)) +#define libssh2_channel_write_stderr(channel, buf, buflen) \ + libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) + +LIBSSH2_API unsigned long +libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, + unsigned long *window_size_initial); +#define libssh2_channel_window_write(channel) \ + libssh2_channel_window_write_ex((channel), NULL) + +LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION* session, + int blocking); +LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION* session); + +LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, + int blocking); + +LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION* session, + long timeout); +LIBSSH2_API long libssh2_session_get_timeout(LIBSSH2_SESSION* session); + +/* libssh2_channel_handle_extended_data is DEPRECATED, do not use! */ +LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, + int ignore_mode); +LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, + int ignore_mode); + +/* libssh2_channel_ignore_extended_data() is defined below for BC with version + * 0.1 + * + * Future uses should use libssh2_channel_handle_extended_data() directly if + * LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read + * (FIFO) from the standard data channel + */ +/* DEPRECATED */ +#define libssh2_channel_ignore_extended_data(channel, ignore) \ + libssh2_channel_handle_extended_data((channel), \ + (ignore) ? \ + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : \ + LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL ) + +#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1 +#define LIBSSH2_CHANNEL_FLUSH_ALL -2 +LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, + int streamid); +#define libssh2_channel_flush(channel) libssh2_channel_flush_ex((channel), 0) +#define libssh2_channel_flush_stderr(channel) \ + libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR) + +LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel); +LIBSSH2_API int libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL* channel, + char **exitsignal, + size_t *exitsignal_len, + char **errmsg, + size_t *errmsg_len, + char **langtag, + size_t *langtag_len); +LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel); + +/* libssh2_scp_recv is DEPRECATED, do not use! */ +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, + const char *path, + struct stat *sb); +/* Use libssh2_scp_recv2 for large (> 2GB) file support on windows */ +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv2(LIBSSH2_SESSION *session, + const char *path, + libssh2_struct_stat *sb); +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, + const char *path, int mode, + size_t size, long mtime, + long atime); +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode, + libssh2_int64_t size, time_t mtime, time_t atime); + +#define libssh2_scp_send(session, path, mode, size) \ + libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0) + +LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, + unsigned int *dest_len, + const char *src, unsigned int src_len); + +LIBSSH2_API +const char *libssh2_version(int req_version_num); + +#define HAVE_LIBSSH2_KNOWNHOST_API 0x010101 /* since 1.1.1 */ +#define HAVE_LIBSSH2_VERSION_API 0x010100 /* libssh2_version since 1.1 */ + +struct libssh2_knownhost { + unsigned int magic; /* magic stored by the library */ + void *node; /* handle to the internal representation of this host */ + char *name; /* this is NULL if no plain text host name exists */ + char *key; /* key in base64/printable format */ + int typemask; +}; + +/* + * libssh2_knownhost_init + * + * Init a collection of known hosts. Returns the pointer to a collection. + * + */ +LIBSSH2_API LIBSSH2_KNOWNHOSTS * +libssh2_knownhost_init(LIBSSH2_SESSION *session); + +/* + * libssh2_knownhost_add + * + * Add a host and its associated key to the collection of known hosts. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +/* host format (2 bits) */ +#define LIBSSH2_KNOWNHOST_TYPE_MASK 0xffff +#define LIBSSH2_KNOWNHOST_TYPE_PLAIN 1 +#define LIBSSH2_KNOWNHOST_TYPE_SHA1 2 /* always base64 encoded */ +#define LIBSSH2_KNOWNHOST_TYPE_CUSTOM 3 + +/* key format (2 bits) */ +#define LIBSSH2_KNOWNHOST_KEYENC_MASK (3<<16) +#define LIBSSH2_KNOWNHOST_KEYENC_RAW (1<<16) +#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16) + +/* type of key (2 bits) */ +#define LIBSSH2_KNOWNHOST_KEY_MASK (7<<18) +#define LIBSSH2_KNOWNHOST_KEY_SHIFT 18 +#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18) +#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18) +#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18) +#define LIBSSH2_KNOWNHOST_KEY_UNKNOWN (7<<18) + +LIBSSH2_API int +libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, + const char *salt, + const char *key, size_t keylen, int typemask, + struct libssh2_knownhost **store); + +/* + * libssh2_knownhost_addc + * + * Add a host and its associated key to the collection of known hosts. + * + * Takes a comment argument that may be NULL. A NULL comment indicates + * there is no comment and the entry will end directly after the key + * when written out to a file. An empty string "" comment will indicate an + * empty comment which will cause a single space to be written after the key. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +LIBSSH2_API int +libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, + const char *salt, + const char *key, size_t keylen, + const char *comment, size_t commentlen, int typemask, + struct libssh2_knownhost **store); + +/* + * libssh2_knownhost_check + * + * Check a host and its associated key against the collection of known hosts. + * + * The type is the type/format of the given host name. + * + * plain - ascii "hostname.domain.tld" + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * + * 'knownhost' may be set to NULL if you don't care about that info. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_* values, see below + * + */ + +#define LIBSSH2_KNOWNHOST_CHECK_MATCH 0 +#define LIBSSH2_KNOWNHOST_CHECK_MISMATCH 1 +#define LIBSSH2_KNOWNHOST_CHECK_NOTFOUND 2 +#define LIBSSH2_KNOWNHOST_CHECK_FAILURE 3 + +LIBSSH2_API int +libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **knownhost); + +/* this function is identital to the above one, but also takes a port + argument that allows libssh2 to do a better check */ +LIBSSH2_API int +libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, int port, + const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **knownhost); + +/* + * libssh2_knownhost_del + * + * Remove a host from the collection of known hosts. The 'entry' struct is + * retrieved by a call to libssh2_knownhost_check(). + * + */ +LIBSSH2_API int +libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *entry); + +/* + * libssh2_knownhost_free + * + * Free an entire collection of known hosts. + * + */ +LIBSSH2_API void +libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts); + +/* + * libssh2_knownhost_readline() + * + * Pass in a line of a file of 'type'. It makes libssh2 read this line. + * + * LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type. + * + */ +LIBSSH2_API int +libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts, + const char *line, size_t len, int type); + +/* + * libssh2_knownhost_readfile + * + * Add hosts+key pairs from a given file. + * + * Returns a negative value for error or number of successfully added hosts. + * + * This implementation currently only knows one 'type' (openssh), all others + * are reserved for future use. + */ + +#define LIBSSH2_KNOWNHOST_FILE_OPENSSH 1 + +LIBSSH2_API int +libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type); + +/* + * libssh2_knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given + * output buffer is too small to hold the desired output. + * + * This implementation currently only knows one 'type' (openssh), all others + * are reserved for future use. + * + */ +LIBSSH2_API int +libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *known, + char *buffer, size_t buflen, + size_t *outlen, /* the amount of written data */ + int type); + +/* + * libssh2_knownhost_writefile + * + * Write hosts+key pairs to a given file. + * + * This implementation currently only knows one 'type' (openssh), all others + * are reserved for future use. + */ + +LIBSSH2_API int +libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type); + +/* + * libssh2_knownhost_get() + * + * Traverse the internal list of known hosts. Pass NULL to 'prev' to get + * the first one. Or pass a poiner to the previously returned one to get the + * next. + * + * Returns: + * 0 if a fine host was stored in 'store' + * 1 if end of hosts + * [negative] on errors + */ +LIBSSH2_API int +libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost **store, + struct libssh2_knownhost *prev); + +#define HAVE_LIBSSH2_AGENT_API 0x010202 /* since 1.2.2 */ + +struct libssh2_agent_publickey { + unsigned int magic; /* magic stored by the library */ + void *node; /* handle to the internal representation of key */ + unsigned char *blob; /* public key blob */ + size_t blob_len; /* length of the public key blob */ + char *comment; /* comment in printable format */ +}; + +/* + * libssh2_agent_init + * + * Init an ssh-agent handle. Returns the pointer to the handle. + * + */ +LIBSSH2_API LIBSSH2_AGENT * +libssh2_agent_init(LIBSSH2_SESSION *session); + +/* + * libssh2_agent_connect() + * + * Connect to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_connect(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_list_identities() + * + * Request an ssh-agent to list identities. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_list_identities(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_get_identity() + * + * Traverse the internal list of public keys. Pass NULL to 'prev' to get + * the first one. Or pass a poiner to the previously returned one to get the + * next. + * + * Returns: + * 0 if a fine public key was stored in 'store' + * 1 if end of public keys + * [negative] on errors + */ +LIBSSH2_API int +libssh2_agent_get_identity(LIBSSH2_AGENT *agent, + struct libssh2_agent_publickey **store, + struct libssh2_agent_publickey *prev); + +/* + * libssh2_agent_userauth() + * + * Do publickey user authentication with the help of ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_userauth(LIBSSH2_AGENT *agent, + const char *username, + struct libssh2_agent_publickey *identity); + +/* + * libssh2_agent_disconnect() + * + * Close a connection to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_disconnect(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_free() + * + * Free an ssh-agent handle. This function also frees the internal + * collection of public keys. + */ +LIBSSH2_API void +libssh2_agent_free(LIBSSH2_AGENT *agent); + + +/* + * libssh2_keepalive_config() + * + * Set how often keepalive messages should be sent. WANT_REPLY + * indicates whether the keepalive messages should request a response + * from the server. INTERVAL is number of seconds that can pass + * without any I/O, use 0 (the default) to disable keepalives. To + * avoid some busy-loop corner-cases, if you specify an interval of 1 + * it will be treated as 2. + * + * Note that non-blocking applications are responsible for sending the + * keepalive messages using libssh2_keepalive_send(). + */ +LIBSSH2_API void libssh2_keepalive_config (LIBSSH2_SESSION *session, + int want_reply, + unsigned interval); + +/* + * libssh2_keepalive_send() + * + * Send a keepalive message if needed. SECONDS_TO_NEXT indicates how + * many seconds you can sleep after this call before you need to call + * it again. Returns 0 on success, or LIBSSH2_ERROR_SOCKET_SEND on + * I/O errors. + */ +LIBSSH2_API int libssh2_keepalive_send (LIBSSH2_SESSION *session, + int *seconds_to_next); + +/* NOTE NOTE NOTE + libssh2_trace() has no function in builds that aren't built with debug + enabled + */ +LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask); +#define LIBSSH2_TRACE_TRANS (1<<1) +#define LIBSSH2_TRACE_KEX (1<<2) +#define LIBSSH2_TRACE_AUTH (1<<3) +#define LIBSSH2_TRACE_CONN (1<<4) +#define LIBSSH2_TRACE_SCP (1<<5) +#define LIBSSH2_TRACE_SFTP (1<<6) +#define LIBSSH2_TRACE_ERROR (1<<7) +#define LIBSSH2_TRACE_PUBLICKEY (1<<8) +#define LIBSSH2_TRACE_SOCKET (1<<9) + +typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*, + void*, + const char *, + size_t); +LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session, + void* context, + libssh2_trace_handler_func callback); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* !RC_INVOKED */ + +#endif /* LIBSSH2_H */ diff --git a/libssh2/include/libssh2_publickey.h b/libssh2/include/libssh2_publickey.h new file mode 100644 index 000000000..0979e23cb --- /dev/null +++ b/libssh2/include/libssh2_publickey.h @@ -0,0 +1,119 @@ +/* Copyright (c) 2004-2006, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +/* Note: This include file is only needed for using the + * publickey SUBSYSTEM which is not the same as publickey + * authentication. For authentication you only need libssh2.h + * + * For more information on the publickey subsystem, + * refer to IETF draft: secsh-publickey + */ + +#ifndef LIBSSH2_PUBLICKEY_H +#define LIBSSH2_PUBLICKEY_H 1 + +#include "libssh2.h" + +typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY; + +typedef struct _libssh2_publickey_attribute { + const char *name; + unsigned long name_len; + const char *value; + unsigned long value_len; + char mandatory; +} libssh2_publickey_attribute; + +typedef struct _libssh2_publickey_list { + unsigned char *packet; /* For freeing */ + + const unsigned char *name; + unsigned long name_len; + const unsigned char *blob; + unsigned long blob_len; + unsigned long num_attrs; + libssh2_publickey_attribute *attrs; /* free me */ +} libssh2_publickey_list; + +/* Generally use the first macro here, but if both name and value are string + literals, you can use _fast() to take advantage of preprocessing */ +#define libssh2_publickey_attribute(name, value, mandatory) \ + { (name), strlen(name), (value), strlen(value), (mandatory) }, +#define libssh2_publickey_attribute_fast(name, value, mandatory) \ + { (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) }, + +#ifdef __cplusplus +extern "C" { +#endif + +/* Publickey Subsystem */ +LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session); + +LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, + const unsigned char *name, + unsigned long name_len, + const unsigned char *blob, + unsigned long blob_len, char overwrite, + unsigned long num_attrs, + const libssh2_publickey_attribute attrs[]); +#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \ + num_attrs, attrs) \ + libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), \ + (overwrite), (num_attrs), (attrs)) + +LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, + const unsigned char *name, + unsigned long name_len, + const unsigned char *blob, + unsigned long blob_len); +#define libssh2_publickey_remove(pkey, name, blob, blob_len) \ + libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len)) + +LIBSSH2_API int +libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, + unsigned long *num_keys, + libssh2_publickey_list **pkey_list); +LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, + libssh2_publickey_list *pkey_list); + +LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef: LIBSSH2_PUBLICKEY_H */ diff --git a/libssh2/include/libssh2_sftp.h b/libssh2/include/libssh2_sftp.h new file mode 100644 index 000000000..677faf2fd --- /dev/null +++ b/libssh2/include/libssh2_sftp.h @@ -0,0 +1,346 @@ +/* Copyright (c) 2004-2008, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBSSH2_SFTP_H +#define LIBSSH2_SFTP_H 1 + +#include "libssh2.h" + +#ifndef WIN32 +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note: Version 6 was documented at the time of writing + * However it was marked as "DO NOT IMPLEMENT" due to pending changes + * + * Let's start with Version 3 (The version found in OpenSSH) and go from there + */ +#define LIBSSH2_SFTP_VERSION 3 + +typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP; +typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE; +typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES; +typedef struct _LIBSSH2_SFTP_STATVFS LIBSSH2_SFTP_STATVFS; + +/* Flags for open_ex() */ +#define LIBSSH2_SFTP_OPENFILE 0 +#define LIBSSH2_SFTP_OPENDIR 1 + +/* Flags for rename_ex() */ +#define LIBSSH2_SFTP_RENAME_OVERWRITE 0x00000001 +#define LIBSSH2_SFTP_RENAME_ATOMIC 0x00000002 +#define LIBSSH2_SFTP_RENAME_NATIVE 0x00000004 + +/* Flags for stat_ex() */ +#define LIBSSH2_SFTP_STAT 0 +#define LIBSSH2_SFTP_LSTAT 1 +#define LIBSSH2_SFTP_SETSTAT 2 + +/* Flags for symlink_ex() */ +#define LIBSSH2_SFTP_SYMLINK 0 +#define LIBSSH2_SFTP_READLINK 1 +#define LIBSSH2_SFTP_REALPATH 2 + +/* SFTP attribute flag bits */ +#define LIBSSH2_SFTP_ATTR_SIZE 0x00000001 +#define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002 +#define LIBSSH2_SFTP_ATTR_PERMISSIONS 0x00000004 +#define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008 +#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000 + +/* SFTP statvfs flag bits */ +#define LIBSSH2_SFTP_ST_RDONLY 0x00000001 +#define LIBSSH2_SFTP_ST_NOSUID 0x00000002 + +struct _LIBSSH2_SFTP_ATTRIBUTES { + /* If flags & ATTR_* bit is set, then the value in this struct will be + * meaningful Otherwise it should be ignored + */ + unsigned long flags; + + libssh2_uint64_t filesize; + unsigned long uid, gid; + unsigned long permissions; + unsigned long atime, mtime; +}; + +struct _LIBSSH2_SFTP_STATVFS { + libssh2_uint64_t f_bsize; /* file system block size */ + libssh2_uint64_t f_frsize; /* fragment size */ + libssh2_uint64_t f_blocks; /* size of fs in f_frsize units */ + libssh2_uint64_t f_bfree; /* # free blocks */ + libssh2_uint64_t f_bavail; /* # free blocks for non-root */ + libssh2_uint64_t f_files; /* # inodes */ + libssh2_uint64_t f_ffree; /* # free inodes */ + libssh2_uint64_t f_favail; /* # free inodes for non-root */ + libssh2_uint64_t f_fsid; /* file system ID */ + libssh2_uint64_t f_flag; /* mount flags */ + libssh2_uint64_t f_namemax; /* maximum filename length */ +}; + +/* SFTP filetypes */ +#define LIBSSH2_SFTP_TYPE_REGULAR 1 +#define LIBSSH2_SFTP_TYPE_DIRECTORY 2 +#define LIBSSH2_SFTP_TYPE_SYMLINK 3 +#define LIBSSH2_SFTP_TYPE_SPECIAL 4 +#define LIBSSH2_SFTP_TYPE_UNKNOWN 5 +#define LIBSSH2_SFTP_TYPE_SOCKET 6 +#define LIBSSH2_SFTP_TYPE_CHAR_DEVICE 7 +#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8 +#define LIBSSH2_SFTP_TYPE_FIFO 9 + +/* + * Reproduce the POSIX file modes here for systems that are not POSIX + * compliant. + * + * These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES" + */ +/* File type */ +#define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */ +#define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */ +#define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */ +#define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */ +#define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */ +#define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */ +#define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */ +#define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */ + +/* File mode */ +/* Read, write, execute/search by owner */ +#define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */ +#define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */ +#define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */ +#define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */ +/* Read, write, execute/search by group */ +#define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */ +#define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */ +#define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */ +#define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */ +/* Read, write, execute/search by others */ +#define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */ +#define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */ +#define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */ +#define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */ + +/* macros to check for specific file types, added in 1.2.5 */ +#define LIBSSH2_SFTP_S_ISLNK(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK) +#define LIBSSH2_SFTP_S_ISREG(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG) +#define LIBSSH2_SFTP_S_ISDIR(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR) +#define LIBSSH2_SFTP_S_ISCHR(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFCHR) +#define LIBSSH2_SFTP_S_ISBLK(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFBLK) +#define LIBSSH2_SFTP_S_ISFIFO(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFIFO) +#define LIBSSH2_SFTP_S_ISSOCK(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFSOCK) + +/* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open()) + * Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */ +#define LIBSSH2_FXF_READ 0x00000001 +#define LIBSSH2_FXF_WRITE 0x00000002 +#define LIBSSH2_FXF_APPEND 0x00000004 +#define LIBSSH2_FXF_CREAT 0x00000008 +#define LIBSSH2_FXF_TRUNC 0x00000010 +#define LIBSSH2_FXF_EXCL 0x00000020 + +/* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */ +#define LIBSSH2_FX_OK 0 +#define LIBSSH2_FX_EOF 1 +#define LIBSSH2_FX_NO_SUCH_FILE 2 +#define LIBSSH2_FX_PERMISSION_DENIED 3 +#define LIBSSH2_FX_FAILURE 4 +#define LIBSSH2_FX_BAD_MESSAGE 5 +#define LIBSSH2_FX_NO_CONNECTION 6 +#define LIBSSH2_FX_CONNECTION_LOST 7 +#define LIBSSH2_FX_OP_UNSUPPORTED 8 +#define LIBSSH2_FX_INVALID_HANDLE 9 +#define LIBSSH2_FX_NO_SUCH_PATH 10 +#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11 +#define LIBSSH2_FX_WRITE_PROTECT 12 +#define LIBSSH2_FX_NO_MEDIA 13 +#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14 +#define LIBSSH2_FX_QUOTA_EXCEEDED 15 +#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16 /* Initial mis-spelling */ +#define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16 +#define LIBSSH2_FX_LOCK_CONFlICT 17 /* Initial mis-spelling */ +#define LIBSSH2_FX_LOCK_CONFLICT 17 +#define LIBSSH2_FX_DIR_NOT_EMPTY 18 +#define LIBSSH2_FX_NOT_A_DIRECTORY 19 +#define LIBSSH2_FX_INVALID_FILENAME 20 +#define LIBSSH2_FX_LINK_LOOP 21 + +/* Returned by any function that would block during a read/write opperation */ +#define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN + +/* SFTP API */ +LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session); +LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp); +LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp); +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp); + +/* File / Directory Ops */ +LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, + const char *filename, + unsigned int filename_len, + unsigned long flags, + long mode, int open_type); +#define libssh2_sftp_open(sftp, filename, flags, mode) \ + libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), \ + (mode), LIBSSH2_SFTP_OPENFILE) +#define libssh2_sftp_opendir(sftp, path) \ + libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, \ + LIBSSH2_SFTP_OPENDIR) + +LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, + char *buffer, size_t buffer_maxlen); + +LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \ + char *buffer, size_t buffer_maxlen, + char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \ + libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, \ + (attrs)) + +LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, + const char *buffer, size_t count); +LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle); + +LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle); +#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle) +#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle) + +LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset); +LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, + libssh2_uint64_t offset); +#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0) + +LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle); +LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle); + +LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_ATTRIBUTES *attrs, + int setstat); +#define libssh2_sftp_fstat(handle, attrs) \ + libssh2_sftp_fstat_ex((handle), (attrs), 0) +#define libssh2_sftp_fsetstat(handle, attrs) \ + libssh2_sftp_fstat_ex((handle), (attrs), 1) + +/* Miscellaneous Ops */ +LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, + const char *source_filename, + unsigned int srouce_filename_len, + const char *dest_filename, + unsigned int dest_filename_len, + long flags); +#define libssh2_sftp_rename(sftp, sourcefile, destfile) \ + libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), \ + (destfile), strlen(destfile), \ + LIBSSH2_SFTP_RENAME_OVERWRITE | \ + LIBSSH2_SFTP_RENAME_ATOMIC | \ + LIBSSH2_SFTP_RENAME_NATIVE) + +LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, + const char *filename, + unsigned int filename_len); +#define libssh2_sftp_unlink(sftp, filename) \ + libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename)) + +LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_STATVFS *st); + +LIBSSH2_API int libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp, + const char *path, + size_t path_len, + LIBSSH2_SFTP_STATVFS *st); + +LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len, long mode); +#define libssh2_sftp_mkdir(sftp, path, mode) \ + libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode)) + +LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len); +#define libssh2_sftp_rmdir(sftp, path) \ + libssh2_sftp_rmdir_ex((sftp), (path), strlen(path)) + +LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len, + int stat_type, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +#define libssh2_sftp_stat(sftp, path, attrs) \ + libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, \ + (attrs)) +#define libssh2_sftp_lstat(sftp, path, attrs) \ + libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, \ + (attrs)) +#define libssh2_sftp_setstat(sftp, path, attrs) \ + libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, \ + (attrs)) + +LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len, + char *target, + unsigned int target_len, int link_type); +#define libssh2_sftp_symlink(sftp, orig, linkpath) \ + libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \ + strlen(linkpath), LIBSSH2_SFTP_SYMLINK) +#define libssh2_sftp_readlink(sftp, path, target, maxlen) \ + libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \ + LIBSSH2_SFTP_READLINK) +#define libssh2_sftp_realpath(sftp, path, target, maxlen) \ + libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \ + LIBSSH2_SFTP_REALPATH) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LIBSSH2_SFTP_H */ diff --git a/libssh2/install-sh b/libssh2/install-sh new file mode 100644 index 000000000..4d4a9519e --- /dev/null +++ b/libssh2/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/libssh2/libssh2.pc.in b/libssh2/libssh2.pc.in new file mode 100644 index 000000000..966381674 --- /dev/null +++ b/libssh2/libssh2.pc.in @@ -0,0 +1,17 @@ +########################################################################### +# libssh2 installation details +########################################################################### + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libssh2 +URL: https://www.libssh2.org/ +Description: Library for SSH-based communication +Version: @LIBSSH2VER@ +Requires.private: @LIBSREQUIRED@ +Libs: -L${libdir} -lssh2 @LIBS@ +Libs.private: @LIBS@ +Cflags: -I${includedir} diff --git a/libssh2/libssh2v.h b/libssh2/libssh2v.h new file mode 100644 index 000000000..966e01394 --- /dev/null +++ b/libssh2/libssh2v.h @@ -0,0 +1,2 @@ +#define LIBSSH2_VERSION_TEXT "Libssh2 1.8.0" + diff --git a/libssh2/ltmain.sh b/libssh2/ltmain.sh new file mode 100644 index 000000000..a736cf994 --- /dev/null +++ b/libssh2/ltmain.sh @@ -0,0 +1,11156 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.6 Debian-2.4.6-2" +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + 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 + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2014-01-07.03; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname $scriptversion Debian-2.4.6-2 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a 'standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to '-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the '--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the 'install' or 'cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with '-') are ignored. + +Every other argument is treated as a filename. Files ending in '.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir=$absdir + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic=$magic + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the '$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the '$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the '$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files + # -stdlib=* select c++ std lib with clang + # -fsanitize=* Clang/GCC memory and address sanitizer + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ + -specs=*|-fsanitize=*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type '$version_type'" + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/libssh2/m4/autobuild.m4 b/libssh2/m4/autobuild.m4 new file mode 100644 index 000000000..2f94844e9 --- /dev/null +++ b/libssh2/m4/autobuild.m4 @@ -0,0 +1,44 @@ +# autobuild.m4 serial 3 +# Copyright (C) 2004, 2006 Simon Josefsson +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# This file can can be used in projects which are not available under +# the GNU General Public License or the GNU Library General Public +# License but which still want to provide support for Autobuild. + +# Usage: AB_INIT([MODE]). +AC_DEFUN([AB_INIT], +[ + AC_REQUIRE([AC_CANONICAL_BUILD]) + AC_REQUIRE([AC_CANONICAL_HOST]) + + if test -z "$AB_PACKAGE"; then + AB_PACKAGE=${PACKAGE_NAME:-$PACKAGE} + fi + AC_MSG_NOTICE([autobuild project... $AB_PACKAGE]) + + if test -z "$AB_VERSION"; then + AB_VERSION=${PACKAGE_VERSION:-$VERSION} + fi + AC_MSG_NOTICE([autobuild revision... $AB_VERSION]) + + hostname=`hostname` + if test "$hostname"; then + AC_MSG_NOTICE([autobuild hostname... $hostname]) + fi + + ifelse([$1],[],,[AC_MSG_NOTICE([autobuild mode... $1])]) + + date=`date +%Y%m%d-%H%M%S` + if test "$?" != 0; then + date=`date` + fi + if test "$date"; then + AC_MSG_NOTICE([autobuild timestamp... $date]) + fi +]) diff --git a/libssh2/m4/lib-ld.m4 b/libssh2/m4/lib-ld.m4 new file mode 100644 index 000000000..96c4e2c33 --- /dev/null +++ b/libssh2/m4/lib-ld.m4 @@ -0,0 +1,110 @@ +# lib-ld.m4 serial 3 (gettext-0.13) +dnl Copyright (C) 1996-2003 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 conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +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 +]) diff --git a/libssh2/m4/lib-link.m4 b/libssh2/m4/lib-link.m4 new file mode 100644 index 000000000..f157d983d --- /dev/null +++ b/libssh2/m4/lib-link.m4 @@ -0,0 +1,709 @@ +# lib-link.m4 serial 13 (gettext-0.16.2) +dnl Copyright (C) 2001-2007 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]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[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 + undefine([Name]) + undefine([NAME]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) +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. If found, it +dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and +dnl 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]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[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" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) + 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 $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]) + undefine([Name]) + undefine([NAME]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl acl_libext, +dnl acl_shlibext, +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_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]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + dnl Autoconf >= 2.61 supports dots in --with options. + define([N_A_M_E],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit([$1],[.],[_])],[$1])]) + 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]N_A_M_E[-prefix], +[ --with-lib]N_A_M_E[-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib + --without-lib]N_A_M_E[-prefix don't search for lib$1 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 +]) + 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= + 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"; 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/"'*$,,'` + LIB[]NAME[]_PREFIX="$basedir" + 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"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; 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 +]) + +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"; 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"; 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]) +]) diff --git a/libssh2/m4/lib-prefix.m4 b/libssh2/m4/lib-prefix.m4 new file mode 100644 index 000000000..a8684e17e --- /dev/null +++ b/libssh2/m4/lib-prefix.m4 @@ -0,0 +1,185 @@ +# lib-prefix.m4 serial 5 (gettext-0.15) +dnl Copyright (C) 2001-2005 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 a variable acl_libdirstem, containing +dnl the basename of the libdir, either "lib" or "lib64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. The current + dnl practice is that on a system supporting 32-bit and 64-bit instruction + dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit + dnl libraries go under $prefix/lib. We determine the compiler's default + dnl mode by looking at the compiler's library search path. If at least + dnl of its elements ends in /lib64 or points to a directory whose absolute + dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the + dnl default, namely "lib". + acl_libdirstem=lib + 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 ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi +]) diff --git a/libssh2/m4/libtool.m4 b/libssh2/m4/libtool.m4 new file mode 100644 index 000000000..ee80844b6 --- /dev/null +++ b/libssh2/m4/libtool.m4 @@ -0,0 +1,8387 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 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. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + 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. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname 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 yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + 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 yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # 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. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + 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 + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + 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 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + 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. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + 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 + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + 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 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/libssh2/m4/ltoptions.m4 b/libssh2/m4/ltoptions.m4 new file mode 100644 index 000000000..94b082976 --- /dev/null +++ b/libssh2/m4/ltoptions.m4 @@ -0,0 +1,437 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# 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. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/libssh2/m4/ltsugar.m4 b/libssh2/m4/ltsugar.m4 new file mode 100644 index 000000000..48bc9344a --- /dev/null +++ b/libssh2/m4/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# 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. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/libssh2/m4/ltversion.m4 b/libssh2/m4/ltversion.m4 new file mode 100644 index 000000000..fa04b52a3 --- /dev/null +++ b/libssh2/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# 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. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/libssh2/m4/lt~obsolete.m4 b/libssh2/m4/lt~obsolete.m4 new file mode 100644 index 000000000..c6b26f88f --- /dev/null +++ b/libssh2/m4/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# 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. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/libssh2/maketgz b/libssh2/maketgz new file mode 100644 index 000000000..b88d9608e --- /dev/null +++ b/libssh2/maketgz @@ -0,0 +1,99 @@ +#! /bin/sh +# Script to build release-archives with +# + +version=$1 + +if [ -z "$version" ]; then + echo "Specify a version number!" + exit +fi + +if [ "xonly" = "x$2" ]; then + echo "Setup version number only!" + only=1 +fi + +libversion="$version" + +major=`echo $libversion |cut -d. -f1 | sed -e "s/[^0-9]//g"` +minor=`echo $libversion |cut -d. -f2 | sed -e "s/[^0-9]//g"` +patch=`echo $libversion |cut -d. -f3 | cut -d- -f1 | sed -e "s/[^0-9]//g"` + +numeric=`perl -e 'printf("%02x%02x%02x\n", '"$major, $minor, $patch);"` + +HEADER=include/libssh2.h + +if test -z "$only"; then + ext=".dist" + # when not setting up version numbers locally + for a in $HEADER; do + cp $a "$a$ext" + done + HEADER="$HEADER$ext" +fi + +# requires a date command that knows -u for UTC time zone +datestamp=`LC_TIME=C date -u` + +# Replace in-place version number in header file: +sed -i -e 's/^#define LIBSSH2_VERSION .*/#define LIBSSH2_VERSION "'$libversion'"/g' \ + -e 's/^#define LIBSSH2_VERSION_NUM .*/#define LIBSSH2_VERSION_NUM 0x'$numeric'/g' \ + -e 's/^#define LIBSSH2_VERSION_MAJOR .*/#define LIBSSH2_VERSION_MAJOR '$major'/g' \ + -e 's/^#define LIBSSH2_VERSION_MINOR .*/#define LIBSSH2_VERSION_MINOR '$minor'/g' \ + -e 's/^#define LIBSSH2_VERSION_PATCH .*/#define LIBSSH2_VERSION_PATCH '$patch'/g' \ + -e "s/^#define LIBSSH2_TIMESTAMP .*/#define LIBSSH2_TIMESTAMP \"$datestamp\"/g" \ + $HEADER + +echo "libssh2 version $libversion" +echo "libssh2 numerical $numeric" +echo "datestamp $datestamp" + +if test -n "$only"; then + # done! + exit; +fi + +findprog() +{ + file="$1" + for part in `echo $PATH| tr ':' ' '`; do + path="$part/$file" + if [ -x "$path" ]; then + # there it is! + return 1 + fi + done + + # no such executable + return 0 +} + +############################################################################ +# +# automake is needed to run to make a non-GNU Makefile.in if Makefile.am has +# been modified. +# + +if { findprog automake >/dev/null 2>/dev/null; } then + echo "- Could not find or run automake, I hope you know what you're doing!" +else + echo "Runs automake --include-deps" + automake --include-deps Makefile >/dev/null +fi + +####################################################################### +# +# Generate the changelog +# +echo "generate NEWS" +git log --pretty=fuller --no-color --date=short --decorate=full -1000 | ./git2news.pl > NEWS.dist + +############################################################################ +# +# Now run make dist to generate a tar.gz archive +# + +echo "make dist" +targz="libssh2-$version.tar.gz" +make -s dist VERSION=$version diff --git a/libssh2/missing b/libssh2/missing new file mode 100644 index 000000000..f62bbae30 --- /dev/null +++ b/libssh2/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2013-10-28.13; # UTC + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libssh2/nw/GNUmakefile b/libssh2/nw/GNUmakefile new file mode 100644 index 000000000..8899fdd8e --- /dev/null +++ b/libssh2/nw/GNUmakefile @@ -0,0 +1,630 @@ +######################################################################### +# +## Makefile for building libssh2 (NetWare version - gnu make) +## Use: make [help|all|clean|dev|devclean|dist|distclean|lib|nlm|objclean] +## +## Hacked by: Guenter Knauf +# +######################################################################### + +# Edit the path below to point to the base of your Novell NDK. +ifndef NDKBASE +NDKBASE = c:/novell +endif + +# Edit the path below to point to the base of your Zlib sources. +ifndef ZLIB_PATH +ZLIB_PATH = ../../zlib-1.2.8 +endif + +# Edit the path below to point to the base of your OpenSSL package. +ifndef OPENSSL_PATH +OPENSSL_PATH = ../../openssl-0.9.8zc +endif + +# Edit the path below to point to your Distribution folder. +ifndef DISTDIR +DISTDIR = libssh2-$(LIBSSH2_VERSION_STR)-bin-nw +endif +DISTARC = $(DISTDIR).zip + +# Edit the path below to point to your Development folder. +ifndef DEVLDIR +DEVLDIR = libssh2-$(LIBSSH2_VERSION_STR)-dev-nw +endif +DEVLARC = $(DEVLDIR).zip + +# Edit the vars below to change NLM target settings. +TARGET = libssh2 +VERSION = $(LIBSSH2_VERSION) +CPRIGHT = Copyright (c) $(LIBSSH2_COPYRIGHT_STR) +WWWURL = https://www.libssh2.org/ +DESCR = libssh2 $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL) +MTSAFE = YES +STACK = 64000 +SCREEN = none +EXPORTS = @$(TARGET).imp + +# Edit the var below to point to your lib architecture. +ifndef LIBARCH +LIBARCH = LIBC +endif + +# must be equal to DEBUG or NDEBUG +ifndef DB + DB = NDEBUG + # DB = DEBUG +endif +# Optimization: -O or debugging: -g +ifeq ($(DB),NDEBUG) + OPT = -O2 + OBJDIR = release +else + OPT = -g + OPT += -DLIBSSH2DEBUG + OBJDIR = debug +endif + +# The following lines defines your compiler. +ifdef CWFolder + METROWERKS = $(CWFolder) +endif +ifdef METROWERKS + # MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support + MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support + CC = mwccnlm +else + CC = $(CROSSPREFIX)gcc +endif + +# Here you can find a native Win32 binary of the original awk: +# http://www.gknw.net/development/prgtools/awk-20100523.zip +AWK = awk +# If you want to mark the target as MTSAFE you will need a tool for +# generating the xdc data for the linker; here's a minimal tool: +# http://www.gknw.net/development/prgtools/mkxdc.zip +MPKXDC = mkxdc +ZIP = zip -qzr9 + +# Platform-dependent helper tool macros +ifeq ($(findstring /sh,$(SHELL)),/sh) +DEL = rm -f $1 +RMDIR = rm -fr $1 +MKDIR = mkdir -p $1 +COPY = -cp -afv $1 $2 +#COPYR = -cp -afr $1/* $2 +COPYR = -rsync -aC $1/* $2 +TOUCH = touch $1 +CAT = cat +ECHONL = echo "" +DL = ' +else +ifeq "$(OS)" "Windows_NT" +DEL = -del 2>NUL /q /f $(subst /,\,$1) +RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) +else +DEL = -del 2>NUL $(subst /,\,$1) +RMDIR = -deltree 2>NUL /y $(subst /,\,$1) +endif +MKDIR = -md 2>NUL $(subst /,\,$1) +COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) +COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2) +TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,, +CAT = type +ECHONL = $(ComSpec) /c echo. +endif + +# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH)) +LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH)) + +# Include the version info retrieved from libssh2.h +-include $(OBJDIR)/version.inc + +# Global flags for all compilers +CFLAGS += $(OPT) -D$(DB) -DNETWARE -nostdinc +#CFLAGS += -DHAVE_CONFIG_H + +ifeq ($(CC),mwccnlm) +LD = mwldnlm +LDFLAGS = -nostdlib $(PRELUDE) $(OBJL) -o $@ -commandfile +AR = mwldnlm +ARFLAGS = -nostdlib -type library -o +LIBEXT = lib +CFLAGS += -msgstyle gcc -gccinc -inline on -opt nointrinsics -proc 586 +CFLAGS += -relax_pointers +#CFLAGS += -w on +ifeq ($(LIBARCH),LIBC) + PRELUDE = $(SDK_LIBC)/imports/libcpre.o + CFLAGS += -align 4 +else + # PRELUDE = $(SDK_CLIB)/imports/clibpre.o + # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK + PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj" + # CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h" + CFLAGS += -align 1 +endif +else +LD = $(CROSSPREFIX)nlmconv +LDFLAGS = -UT +AR = $(CROSSPREFIX)ar +ARFLAGS = -cq +LIBEXT = a +RANLIB = $(CROSSPREFIX)ranlib +CFLAGS += -m32 +CFLAGS += -fno-builtin -fpcc-struct-return +CFLAGS += -fno-strict-aliasing +CFLAGS += -Wall # -pedantic +#CFLAGS += -Wno-pointer-sign +ifeq ($(LIBARCH),LIBC) + PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o +else + # PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o + # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK + # http://www.gknw.net/development/mk_nlm/gcc_pre.zip + PRELUDE = $(NDK_ROOT)/pre/prelude.o + CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h +endif +endif + +LDLIBS = + +NDK_ROOT = $(NDKBASE)/ndk +SDK_CLIB = $(NDK_ROOT)/nwsdk +SDK_LIBC = $(NDK_ROOT)/libc +SNPRINTF = $(NDKBASE)/snprintf + +INCLUDES = -I. -I../include + +ifdef WITH_ZLIB + INCLUDES += -I$(ZLIB_PATH) +ifdef LINK_STATIC + LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT) +else + MODULES += libz.nlm + IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp +endif +endif +INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L) +LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT) +LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT) +IMPORTS += GetProcessSwitchCount RunningProcess + +ifeq ($(LIBARCH),LIBC) + INCLUDES += -I$(SDK_LIBC)/include + # INCLUDES += -I$(SDK_LIBC)/include/nks + # INCLUDES += -I$(SDK_LIBC)/include/winsock + CFLAGS += -D_POSIX_SOURCE +else + INCLUDES += -I$(SDK_CLIB)/include/nlm + # INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete + # INCLUDES += -I$(SDK_CLIB)/include +endif +CFLAGS += $(INCLUDES) + +ifeq ($(MTSAFE),YES) + XDCOPT = -n +endif +ifeq ($(MTSAFE),NO) + XDCOPT = -u +endif +ifdef XDCOPT + XDCDATA = $(OBJDIR)/$(TARGET).xdc +endif + +vpath %.c . ../src + +# only OpenSSL is supported with this build system +CFLAGS += -DLIBSSH2_OPENSSL +include ../Makefile.OpenSSL.inc + +# include Makefile.inc to get CSOURCES define +include ../Makefile.inc + +OBJECTS := $(patsubst %.c,%.o,$(CSOURCES)) +ifeq ($(LIBARCH),CLIB) +# CLIB lacks of snprint() function - here's a replacement: +# https://www.ijs.si/software/snprintf/ +OBJECTS += snprintf.o +vpath %.c $(SNPRINTF) +endif + +OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS)) +OBJL = $(OBJS) $(OBJDIR)/nwlib.o $(LDLIBS) + +all: lib nlm + +nlm: prebuild $(TARGET).nlm + +lib: prebuild $(TARGET).$(LIBEXT) + +prebuild: $(OBJDIR) $(OBJDIR)/version.inc libssh2_config.h + +test: all + $(MAKE) -C test + +$(OBJDIR)/%.o: %.c +# @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)/version.inc: ../get_ver.awk ../include/libssh2.h $(OBJDIR) + @echo Creating $@ + @$(AWK) -f $^ > $@ + +dist: all $(DISTDIR) $(DISTDIR)/readme.txt + @$(call MKDIR, $(DISTDIR)/bin) + @$(call COPY, ../AUTHORS, $(DISTDIR)) + @$(call COPY, ../COPYING, $(DISTDIR)) + @$(call COPY, ../INSTALL, $(DISTDIR)) + @$(call COPY, ../README, $(DISTDIR)) + @$(call COPY, ../RELEASE-NOTES, $(DISTDIR)) + @$(call COPY, $(TARGET).nlm, $(DISTDIR)/bin) + @echo Creating $(DISTARC) + @$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt + +dev: all $(DEVLDIR) $(DEVLDIR)/readme.txt + @$(call MKDIR, $(DEVLDIR)/bin) + @$(call MKDIR, $(DEVLDIR)/include) + @$(call MKDIR, $(DEVLDIR)/nw) + @$(call COPY, ../AUTHORS, $(DEVLDIR)) + @$(call COPY, ../COPYING, $(DEVLDIR)) + @$(call COPY, ../INSTALL, $(DEVLDIR)) + @$(call COPY, ../README, $(DEVLDIR)) + @$(call COPY, ../RELEASE-NOTES, $(DEVLDIR)) + @$(call COPY, ../include/*.h, $(DEVLDIR)/include) + @$(call COPY, libssh2_config.h, $(DEVLDIR)/include) + @$(call COPY, $(TARGET).nlm, $(DEVLDIR)/bin) + @$(call COPY, $(TARGET).imp, $(DEVLDIR)/nw) + @$(call COPY, $(TARGET).$(LIBEXT), $(DEVLDIR)/nw) + @echo Creating $(DEVLARC) + @$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt + +distclean: clean + $(call RMDIR, $(DISTDIR)) + $(call DEL, $(DISTARC)) + +devclean: clean + $(call RMDIR, $(DEVLDIR)) + $(call DEL, $(DEVLARC)) + +objclean: + $(call RMDIR, $(OBJDIR)) + +testclean: clean + $(MAKE) -C test clean + +clean: objclean + $(call DEL, libssh2_config.h) + $(call DEL, $(TARGET).*) + +$(OBJDIR): + @$(call MKDIR, $@) + +$(DISTDIR): + @$(call MKDIR, $@) + +$(DEVLDIR): + @$(call MKDIR, $@) + +$(TARGET).$(LIBEXT): $(OBJS) + @echo Creating $@ + @$(call DEL, $@) + @$(AR) $(ARFLAGS) $@ $^ +ifdef RANLIB + @$(RANLIB) $@ +endif + +$(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(TARGET).imp $(OBJL) $(XDCDATA) + @echo Linking $@ + @$(call DEL, $@) + @$(LD) $(LDFLAGS) $< + +$(OBJDIR)/%.xdc: GNUmakefile + @echo Creating $@ + @$(MPKXDC) $(XDCOPT) $@ + +$(OBJDIR)/%.def: GNUmakefile + @echo $(DL)# DEF file for linking with $(LD)$(DL) > $@ + @echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@ + @echo $(DL)# All your changes will be lost!!$(DL) >> $@ + @echo $(DL)#$(DL) >> $@ + @echo $(DL)copyright "$(CPRIGHT)"$(DL) >> $@ + @echo $(DL)description "$(DESCR)"$(DL) >> $@ + @echo $(DL)version $(VERSION)$(DL) >> $@ +ifdef NLMTYPE + @echo $(DL)type $(NLMTYPE)$(DL) >> $@ +endif +ifdef STACK + @echo $(DL)stack $(STACK)$(DL) >> $@ +endif +ifdef SCREEN + @echo $(DL)screenname "$(SCREEN)"$(DL) >> $@ +else + @echo $(DL)screenname "DEFAULT"$(DL) >> $@ +endif +ifeq ($(DB),DEBUG) + @echo $(DL)debug$(DL) >> $@ +endif + @echo $(DL)threadname "$(TARGET)"$(DL) >> $@ +ifdef XDCDATA + @echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@ +endif + @echo $(DL)flag_on 64$(DL) >> $@ +ifeq ($(LIBARCH),CLIB) + @echo $(DL)start _Prelude$(DL) >> $@ + @echo $(DL)exit _Stop$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/clib.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@ + @echo $(DL)module clib$(DL) >> $@ +else + @echo $(DL)pseudopreemption$(DL) >> $@ + @echo $(DL)start _LibCPrelude$(DL) >> $@ + @echo $(DL)exit _LibCPostlude$(DL) >> $@ + @echo $(DL)check _LibCCheckUnload$(DL) >> $@ + @echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@ + @echo $(DL)module libc$(DL) >> $@ +endif +ifdef MODULES + @echo $(DL)module $(MODULES)$(DL) >> $@ +endif +ifdef EXPORTS + @echo $(DL)export $(EXPORTS)$(DL) >> $@ +endif +ifdef IMPORTS + @echo $(DL)import $(IMPORTS)$(DL) >> $@ +endif +ifeq ($(LD),nlmconv) + @echo $(DL)input $(OBJL)$(DL) >> $@ + @echo $(DL)input $(PRELUDE)$(DL) >> $@ + @echo $(DL)output $(TARGET).nlm$(DL) >> $@ +endif + +libssh2_config.h: GNUmakefile + @echo Creating $@ + @echo $(DL)/* $@ for NetWare target.$(DL) > $@ + @echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@ + @echo $(DL)** All your changes will be lost!!$(DL) >> $@ + @echo $(DL)*/$(DL) >> $@ + @echo $(DL)#define VERSION "$(LIBSSH2_VERSION_STR)"$(DL) >> $@ + @echo $(DL)#define PACKAGE_BUGREPORT "https://github.com/libssh2/libssh2/issues"$(DL) >> $@ +ifeq ($(LIBARCH),CLIB) + @echo $(DL)#define OS "i586-pc-clib-NetWare"$(DL) >> $@ + @echo $(DL)#define NETDB_USE_INTERNET 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRICMP 1$(DL) >> $@ + @echo $(DL)#define socklen_t int$(DL) >> $@ + @echo $(DL)#define sleep(s) delay(1000 * s)$(DL) >> $@ + @echo $(DL)#define strcasecmp stricmp$(DL) >> $@ + @echo $(DL)#define strncasecmp strnicmp$(DL) >> $@ +else + @echo $(DL)#define OS "i586-pc-libc-NetWare"$(DL) >> $@ + @echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_DLOPEN 1$(DL) >> $@ + @echo $(DL)#define HAVE_FTRUNCATE 1$(DL) >> $@ + @echo $(DL)#define HAVE_GETTIMEOFDAY 1$(DL) >> $@ + @echo $(DL)#define HAVE_INET_PTON 1$(DL) >> $@ + @echo $(DL)#define HAVE_INTTYPES_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_LIMITS_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_LONGLONG 1$(DL) >> $@ + @echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRCASECMP 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRLCAT 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRLCPY 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRTOLL 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_PARAM_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_SELECT_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_TERMIOS_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@ + @echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@ + @echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@ +ifdef ENABLE_IPV6 + @echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@ +endif +endif + @echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_CTYPE_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_ERRNO_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_FIONBIO 1$(DL) >> $@ + @echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@ + @echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@ + @echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@ + @echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@ + @echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@ + @echo $(DL)#define HAVE_INET_NTOA 1$(DL) >> $@ + @echo $(DL)#define HAVE_LL 1$(DL) >> $@ + @echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@ + @echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SELECT 1$(DL) >> $@ + @echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@ + @echo $(DL)#define HAVE_SIGNAL_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SIG_ATOMIC_T 1$(DL) >> $@ + @echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@ + @echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRDUP 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRFTIME 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRING_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRSTR 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@ + @echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_IOCTL_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_STAT_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_TIME_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_TIME_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_UNAME 1$(DL) >> $@ + @echo $(DL)#define HAVE_UNISTD_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_UTIME 1$(DL) >> $@ + @echo $(DL)#define HAVE_UTIME_H 1$(DL) >> $@ + @echo $(DL)#define RETSIGTYPE void$(DL) >> $@ + @echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@ + @echo $(DL)#define STDC_HEADERS 1$(DL) >> $@ + @echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@ + @echo $(DL)#define USE_SSLEAY 1$(DL) >> $@ + @echo $(DL)#define USE_OPENSSL 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_X509_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_SSL_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_RSA_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_PEM_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_ERR_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_CRYPTO_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_OPENSSL_ENGINE_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_O_NONBLOCK 1$(DL) >> $@ + @echo $(DL)#define HAVE_LIBSSL 1$(DL) >> $@ + @echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@ + @echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@ +ifdef WITH_ZLIB + @echo $(DL)#define HAVE_ZLIB_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_LIBZ 1$(DL) >> $@ + @echo $(DL)#define LIBSSH2_HAVE_ZLIB 1$(DL) >> $@ +endif +ifdef NW_WINSOCK + @echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@ +else + @echo $(DL)#define HAVE_SYS_TYPES_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_SOCKET_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_SYS_SOCKIO_H 1$(DL) >> $@ + @echo $(DL)#define HAVE_NETDB_H 1$(DL) >> $@ +endif +ifdef OLD_NOVELLSDK + @echo $(DL)#define socklen_t int$(DL) >> $@ +endif + @echo $(DL)#define LIBSSH2_DH_GEX_NEW 1$(DL) >> $@ +ifeq ($(DB),DEBUG) + @echo $(DL)#define LIBSSH2_DEBUG_CONNECTION 1$(DL) >> $@ + @echo $(DL)#define LIBSSH2_DEBUG_ERRORS 1$(DL) >> $@ + @echo $(DL)#define LIBSSH2_DEBUG_KEX 1$(DL) >> $@ + @echo $(DL)#define LIBSSH2_DEBUG_PUBLICKEY 1$(DL) >> $@ + @echo $(DL)#define LIBSSH2_DEBUG_SCP 1$(DL) >> $@ + @echo $(DL)#define LIBSSH2_DEBUG_SFTP 1$(DL) >> $@ + @echo $(DL)#define LIBSSH2_DEBUG_TRANSPORT 1$(DL) >> $@ + @echo $(DL)#define LIBSSH2_DEBUG_USERAUTH 1$(DL) >> $@ +endif + +libssh2.imp: GNUmakefile + @echo Creating $@ + @echo $(DL)# $@ for NetWare target.$(DL) > $@ + @echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@ + @echo $(DL)# All your changes will be lost!!$(DL) >> $@ +ifeq ($(LIBARCH),CLIB) + @echo $(DL) (CLIB_LIBSSH2)$(DL) >> $@ +else + @echo $(DL) (LIBC_LIBSSH2)$(DL) >> $@ +endif + @echo $(DL) libssh2_banner_set,$(DL) >> $@ + @echo $(DL) libssh2_channel_close,$(DL) >> $@ + @echo $(DL) libssh2_channel_direct_tcpip_ex,$(DL) >> $@ + @echo $(DL) libssh2_channel_eof,$(DL) >> $@ + @echo $(DL) libssh2_channel_flush_ex,$(DL) >> $@ + @echo $(DL) libssh2_channel_free,$(DL) >> $@ + @echo $(DL) libssh2_channel_get_exit_status,$(DL) >> $@ + @echo $(DL) libssh2_channel_open_ex,$(DL) >> $@ + @echo $(DL) libssh2_channel_process_startup,$(DL) >> $@ + @echo $(DL) libssh2_channel_read_ex,$(DL) >> $@ + @echo $(DL) libssh2_channel_request_pty_ex,$(DL) >> $@ + @echo $(DL) libssh2_channel_send_eof,$(DL) >> $@ + @echo $(DL) libssh2_channel_set_blocking,$(DL) >> $@ + @echo $(DL) libssh2_channel_setenv_ex,$(DL) >> $@ + @echo $(DL) libssh2_channel_wait_closed,$(DL) >> $@ + @echo $(DL) libssh2_channel_wait_eof,$(DL) >> $@ + @echo $(DL) libssh2_channel_write_ex,$(DL) >> $@ + @echo $(DL) libssh2_exit,$(DL) >> $@ + @echo $(DL) libssh2_hostkey_hash,$(DL) >> $@ + @echo $(DL) libssh2_init,$(DL) >> $@ + @echo $(DL) libssh2_knownhost_add,$(DL) >> $@ + @echo $(DL) libssh2_knownhost_check,$(DL) >> $@ + @echo $(DL) libssh2_knownhost_checkp,$(DL) >> $@ + @echo $(DL) libssh2_knownhost_free,$(DL) >> $@ + @echo $(DL) libssh2_knownhost_init,$(DL) >> $@ + @echo $(DL) libssh2_knownhost_readfile,$(DL) >> $@ + @echo $(DL) libssh2_knownhost_writefile,$(DL) >> $@ + @echo $(DL) libssh2_scp_recv,$(DL) >> $@ + @echo $(DL) libssh2_scp_recv2,$(DL) >> $@ + @echo $(DL) libssh2_scp_send64,$(DL) >> $@ + @echo $(DL) libssh2_scp_send_ex,$(DL) >> $@ + @echo $(DL) libssh2_session_abstract,$(DL) >> $@ + @echo $(DL) libssh2_session_block_directions,$(DL) >> $@ + @echo $(DL) libssh2_session_callback_set,$(DL) >> $@ + @echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@ + @echo $(DL) libssh2_session_free,$(DL) >> $@ + @echo $(DL) libssh2_session_handshake,$(DL) >> $@ + @echo $(DL) libssh2_session_hostkey,$(DL) >> $@ + @echo $(DL) libssh2_session_init_ex,$(DL) >> $@ + @echo $(DL) libssh2_session_last_errno,$(DL) >> $@ + @echo $(DL) libssh2_session_last_error,$(DL) >> $@ + @echo $(DL) libssh2_session_method_pref,$(DL) >> $@ + @echo $(DL) libssh2_session_methods,$(DL) >> $@ + @echo $(DL) libssh2_session_set_blocking,$(DL) >> $@ + @echo $(DL) libssh2_session_startup,$(DL) >> $@ + @echo $(DL) libssh2_sftp_close_handle,$(DL) >> $@ + @echo $(DL) libssh2_sftp_fstat_ex,$(DL) >> $@ + @echo $(DL) libssh2_sftp_init,$(DL) >> $@ + @echo $(DL) libssh2_sftp_last_error,$(DL) >> $@ + @echo $(DL) libssh2_sftp_mkdir_ex,$(DL) >> $@ + @echo $(DL) libssh2_sftp_open_ex,$(DL) >> $@ + @echo $(DL) libssh2_sftp_read,$(DL) >> $@ + @echo $(DL) libssh2_sftp_readdir_ex,$(DL) >> $@ + @echo $(DL) libssh2_sftp_rename_ex,$(DL) >> $@ + @echo $(DL) libssh2_sftp_rmdir_ex,$(DL) >> $@ + @echo $(DL) libssh2_sftp_seek,$(DL) >> $@ + @echo $(DL) libssh2_sftp_seek64,$(DL) >> $@ + @echo $(DL) libssh2_sftp_shutdown,$(DL) >> $@ + @echo $(DL) libssh2_sftp_stat_ex,$(DL) >> $@ + @echo $(DL) libssh2_sftp_symlink_ex,$(DL) >> $@ + @echo $(DL) libssh2_sftp_tell,$(DL) >> $@ + @echo $(DL) libssh2_sftp_unlink_ex,$(DL) >> $@ + @echo $(DL) libssh2_sftp_write,$(DL) >> $@ + @echo $(DL) libssh2_trace,$(DL) >> $@ + @echo $(DL) libssh2_userauth_authenticated,$(DL) >> $@ + @echo $(DL) libssh2_userauth_keyboard_interactive_ex,$(DL) >> $@ + @echo $(DL) libssh2_userauth_list,$(DL) >> $@ + @echo $(DL) libssh2_userauth_password_ex,$(DL) >> $@ + @echo $(DL) libssh2_userauth_publickey_fromfile_ex,$(DL) >> $@ + @echo $(DL) libssh2_version$(DL) >> $@ + +$(DISTDIR)/readme.txt: GNUmakefile + @echo Creating $@ + @echo $(DL)This is a binary distribution for NetWare platform.$(DL) > $@ + @echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@ + @echo $(DL)Please download the complete libssh package for$(DL) >> $@ + @echo $(DL)any further documentation:$(DL) >> $@ + @echo $(DL)$(WWWURL)$(DL) >> $@ + +$(DEVLDIR)/readme.txt: GNUmakefile + @echo Creating $@ + @echo $(DL)This is a development distribution for NetWare platform.$(DL) > $@ + @echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@ + @echo $(DL)Please download the complete libssh2 package for$(DL) >> $@ + @echo $(DL)any further documentation:$(DL) >> $@ + @echo $(DL)$(WWWURL)$(DL) >> $@ + +help: $(OBJDIR)/version.inc + @echo $(DL)===========================================================$(DL) +ifeq ($(LIBARCH),LIBC) + @echo $(DL)Novell LibC NDK = $(SDK_LIBC)$(DL) +else + @echo $(DL)Novell CLib NDK = $(SDK_CLIB)$(DL) +endif + @echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL) + @echo $(DL)Zlib path = $(ZLIB_PATH)$(DL) + @echo $(DL)===========================================================$(DL) + @echo $(DL)libssh $(LIBSSH2_VERSION_STR) - available targets are:$(DL) + @echo $(DL)$(MAKE) all$(DL) + @echo $(DL)$(MAKE) nlm$(DL) + @echo $(DL)$(MAKE) lib$(DL) + @echo $(DL)$(MAKE) clean$(DL) + @echo $(DL)$(MAKE) dev$(DL) + @echo $(DL)$(MAKE) devclean$(DL) + @echo $(DL)$(MAKE) dist$(DL) + @echo $(DL)$(MAKE) distclean$(DL) + @echo $(DL)$(MAKE) objclean$(DL) + @echo $(DL)$(MAKE) test$(DL) + @echo $(DL)===========================================================$(DL) + + diff --git a/libssh2/nw/keepscreen.c b/libssh2/nw/keepscreen.c new file mode 100644 index 000000000..c3471b3e0 --- /dev/null +++ b/libssh2/nw/keepscreen.c @@ -0,0 +1,25 @@ +/* Simple _NonAppStop() implementation which can be linked to your + * NLM in order to keep the screen open when the NLM terminates + * (the good old clib behaviour). + * You dont have to call it, its done automatically from LibC. + * + * 2004-Aug-11 by Guenter Knauf + * + * URL: http://www.gknw.net/development/mk_nlm/ + */ + +#include +#include + +void _NonAppStop() +{ + uint16_t row, col; + + GetScreenSize(&row, &col); + gotorowcol(row-1, 0); + /* pressanykey(); */ + printf(" "); + getcharacter(); +} + + diff --git a/libssh2/nw/nwlib.c b/libssh2/nw/nwlib.c new file mode 100644 index 000000000..43018e59a --- /dev/null +++ b/libssh2/nw/nwlib.c @@ -0,0 +1,304 @@ +/********************************************************************* + * Universal NetWare library stub. * + * written by Ulrich Neuman and given to OpenSource copyright-free. * + * Extended for CLIB support by Guenter Knauf. * + *********************************************************************/ + +#ifdef NETWARE /* Novell NetWare */ + +#include + +#ifdef __NOVELL_LIBC__ +/* For native LibC-based NLM we need to register as a real lib. */ +#include +#include +#include +#include +#include +#include +#include + +typedef struct +{ + int _errno; + void *twentybytes; +} libthreaddata_t; + +typedef struct +{ + int x; + int y; + int z; + void *tenbytes; + NXKey_t perthreadkey; /* if -1, no key obtained... */ + NXMutex_t *lock; +} libdata_t; + +int gLibId = -1; +void *gLibHandle = (void *) NULL; +rtag_t gAllocTag = (rtag_t) NULL; +NXMutex_t *gLibLock = (NXMutex_t *) NULL; + +/* internal library function prototypes... */ +int DisposeLibraryData ( void * ); +void DisposeThreadData ( void * ); +int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata ); + + +int _NonAppStart( void *NLMHandle, + void *errorScreen, + const char *cmdLine, + const char *loadDirPath, + size_t uninitializedDataLength, + void *NLMFileHandle, + int (*readRoutineP)( int conn, + void *fileHandle, size_t offset, + size_t nbytes, + size_t *bytesRead, + void *buffer ), + size_t customDataOffset, + size_t customDataSize, + int messageCount, + const char **messages ) +{ + NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0); + +#ifndef __GNUC__ +#pragma unused(cmdLine) +#pragma unused(loadDirPath) +#pragma unused(uninitializedDataLength) +#pragma unused(NLMFileHandle) +#pragma unused(readRoutineP) +#pragma unused(customDataOffset) +#pragma unused(customDataSize) +#pragma unused(messageCount) +#pragma unused(messages) +#endif + +/* +** Here we process our command line, post errors (to the error screen), +** perform initializations and anything else we need to do before being able +** to accept calls into us. If we succeed, we return non-zero and the NetWare +** Loader will leave us up, otherwise we fail to load and get dumped. +*/ + gAllocTag = AllocateResourceTag(NLMHandle, + " memory allocations", AllocSignature); + + if (!gAllocTag) { + OutputToScreen(errorScreen, "Unable to allocate resource tag for " + "library memory allocations.\n"); + return -1; + } + + gLibId = register_library(DisposeLibraryData); + + if (gLibId < -1) { + OutputToScreen(errorScreen, "Unable to register library with kernel.\n"); + return -1; + } + + gLibHandle = NLMHandle; + + gLibLock = NXMutexAlloc(0, 0, &liblock); + + if (!gLibLock) { + OutputToScreen(errorScreen, "Unable to allocate library data lock.\n"); + return -1; + } + + return 0; +} + +/* +** Here we clean up any resources we allocated. Resource tags is a big part +** of what we created, but NetWare doesn't ask us to free those. +*/ +void _NonAppStop( void ) +{ + (void) unregister_library(gLibId); + NXMutexFree(gLibLock); +} + +/* +** This function cannot be the first in the file for if the file is linked +** first, then the check-unload function's offset will be nlmname.nlm+0 +** which is how to tell that there isn't one. When the check function is +** first in the linked objects, it is ambiguous. For this reason, we will +** put it inside this file after the stop function. +** +** Here we check to see if it's alright to ourselves to be unloaded. If not, +** we return a non-zero value. Right now, there isn't any reason not to allow +** it. +*/ +int _NonAppCheckUnload( void ) +{ + return 0; +} + +int GetOrSetUpData(int id, libdata_t **appData, libthreaddata_t **threadData) +{ + int err; + libdata_t *app_data; + libthreaddata_t *thread_data; + NXKey_t key; + NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0); + + err = 0; + thread_data = (libthreaddata_t *) NULL; + +/* +** Attempt to get our data for the application calling us. This is where we +** store whatever application-specific information we need to carry in support +** of calling applications. +*/ + app_data = (libdata_t *) get_app_data(id); + + if (!app_data) { +/* +** This application hasn't called us before; set up application AND per-thread +** data. Of course, just in case a thread from this same application is calling +** us simultaneously, we better lock our application data-creation mutex. We +** also need to recheck for data after we acquire the lock because WE might be +** that other thread that was too late to create the data and the first thread +** in will have created it. +*/ + NXLock(gLibLock); + + if (!(app_data = (libdata_t *) get_app_data(id))) { + app_data = (libdata_t *) malloc(sizeof(libdata_t)); + + if (app_data) { + memset(app_data, 0, sizeof(libdata_t)); + + app_data->tenbytes = malloc(10); + app_data->lock = NXMutexAlloc(0, 0, &liblock); + + if (!app_data->tenbytes || !app_data->lock) { + if (app_data->lock) + NXMutexFree(app_data->lock); + + free(app_data); + app_data = (libdata_t *) NULL; + err = ENOMEM; + } + + if (app_data) { +/* +** Here we burn in the application data that we were trying to get by calling +** get_app_data(). Next time we call the first function, we'll get this data +** we're just now setting. We also go on here to establish the per-thread data +** for the calling thread, something we'll have to do on each application +** thread the first time it calls us. +*/ + err = set_app_data(gLibId, app_data); + + if (err) { + free(app_data); + app_data = (libdata_t *) NULL; + err = ENOMEM; + } + else { + /* create key for thread-specific data... */ + err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key); + + if (err) /* (no more keys left?) */ + key = -1; + + app_data->perthreadkey = key; + } + } + } + } + + NXUnlock(gLibLock); + } + + if (app_data) { + key = app_data->perthreadkey; + + if (key != -1 /* couldn't create a key? no thread data */ + && !(err = NXKeyGetValue(key, (void **) &thread_data)) + && !thread_data) { +/* +** Allocate the per-thread data for the calling thread. Regardless of whether +** there was already application data or not, this may be the first call by a +** a new thread. The fact that we allocation 20 bytes on a pointer is not very +** important, this just helps to demonstrate that we can have arbitrarily +** complex per-thread data. +*/ + thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t)); + + if (thread_data) { + thread_data->_errno = 0; + thread_data->twentybytes = malloc(20); + + if (!thread_data->twentybytes) { + free(thread_data); + thread_data = (libthreaddata_t *) NULL; + err = ENOMEM; + } + + if ((err = NXKeySetValue(key, thread_data))) { + free(thread_data->twentybytes); + free(thread_data); + thread_data = (libthreaddata_t *) NULL; + } + } + } + } + + if (appData) + *appData = app_data; + + if (threadData) + *threadData = thread_data; + + return err; +} + +int DisposeLibraryData( void *data ) +{ + if (data) { + void *tenbytes = ((libdata_t *) data)->tenbytes; + + if (tenbytes) + free(tenbytes); + + free(data); + } + + return 0; +} + +void DisposeThreadData( void *data ) +{ + if (data) { + void *twentybytes = ((libthreaddata_t *) data)->twentybytes; + + if (twentybytes) + free(twentybytes); + + free(data); + } +} + +#else /* __NOVELL_LIBC__ */ +/* For native CLib-based NLM seems we can do a bit more simple. */ +#include + +int main ( void ) +{ + /* initialize any globals here... */ + + /* do this if any global initializing was done + SynchronizeStart(); + */ + ExitThread (TSR_THREAD, 0); + return 0; +} + +#endif /* __NOVELL_LIBC__ */ + +#endif /* NETWARE */ + + diff --git a/libssh2/nw/test/GNUmakefile b/libssh2/nw/test/GNUmakefile new file mode 100644 index 000000000..86bf6b684 --- /dev/null +++ b/libssh2/nw/test/GNUmakefile @@ -0,0 +1,311 @@ +######################################################################### +# +## Makefile for building libssh2 (NetWare version - gnu make) +## +## Hacked by: Guenter Knauf +# +######################################################################### + +# Edit the path below to point to the base of your Novell NDK. +ifndef NDKBASE +NDKBASE = c:/novell +endif + +# Edit the path below to point to the base of your Zlib sources. +ifndef ZLIB_PATH +ZLIB_PATH = ../../../zlib-1.2.8 +endif + +# Edit the path below to point to the base of your OpenSSL package. +ifndef OPENSSL_PATH +OPENSSL_PATH = ../../../openssl-0.9.8zc +endif + +# Edit the var below to enable static linking of libssh2 and libz +LINK_STATIC = 1 + +# Edit the vars below to change NLM target settings. +SAMPLES = ../../example +TARGETS := $(filter-out x11.nlm,$(patsubst $(SAMPLES)/%.c,%.nlm,$(strip $(wildcard $(SAMPLES)/*.c)))) +VERSION = $(LIBSSH2_VERSION) +COPYR = Copyright (c) $(LIBSSH2_COPYRIGHT_STR) +WWWURL = http://www.libssh2.org/ +DESCR = libssh2 $(notdir $(@:.def=)) $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL) +MTSAFE = YES +STACK = 64000 +SCREEN = NONE +#SCREEN = libssh2 $(notdir $(@:.def=)) +# Comment the line below if you dont want to load protected automatically. +#LDRING = 3 + +# Edit the var below to point to your lib architecture. +ifndef LIBARCH +LIBARCH = LIBC +endif + +# must be equal to DEBUG or NDEBUG +ifndef DB + DB = NDEBUG + # DB = DEBUG +endif +# Optimization: -O or debugging: -g +ifeq ($(DB),NDEBUG) + OPT = -O2 + OBJDIR = release +else + OPT = -g + OPT += -DLIBSSH2DEBUG + OBJDIR = debug +endif + +# The following lines defines your compiler. +ifdef CWFolder + METROWERKS = $(CWFolder) +endif +ifdef METROWERKS + # MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support + MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support + CC = mwccnlm +else + CC = $(CROSSPREFIX)gcc +endif + +# Here you can find a native Win32 binary of the original awk: +# http://www.gknw.net/development/prgtools/awk-20100523.zip +AWK = awk +# If you want to mark the target as MTSAFE you will need a tool for +# generating the xdc data for the linker; here's a minimal tool: +# http://www.gknw.net/development/prgtools/mkxdc.zip +MPKXDC = mkxdc + +# Platform-dependent helper tool macros +ifeq ($(findstring /sh,$(SHELL)),/sh) +DEL = rm -f $1 +RMDIR = rm -fr $1 +MKDIR = mkdir -p $1 +COPY = -cp -afv $1 $2 +#COPYR = -cp -afr $1/* $2 +COPYR = -rsync -aC $1/* $2 +TOUCH = touch $1 +CAT = cat +ECHONL = echo "" +DL = ' +else +ifeq "$(OS)" "Windows_NT" +DEL = -del 2>NUL /q /f $(subst /,\,$1) +RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) +else +DEL = -del 2>NUL $(subst /,\,$1) +RMDIR = -deltree 2>NUL /y $(subst /,\,$1) +endif +MKDIR = -md 2>NUL $(subst /,\,$1) +COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) +COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2) +TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,, +CAT = type +ECHONL = $(ComSpec) /c echo. +endif + +# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH)) +LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH)) + +# Include the version info retrieved from libssh2.h +-include $(OBJDIR)/version.inc + +# Global flags for all compilers +CFLAGS += $(OPT) -D$(DB) -DNETWARE -nostdinc + +ifeq ($(CC),mwccnlm) +LD = mwldnlm +LDFLAGS = -nostdlib $(<:.def=.o) $(PRELUDE) $(LDLIBS) -o $@ -commandfile +AR = mwldnlm +ARFLAGS = -type library -w nocmdline $(OBJS) -o +LIBEXT = lib +CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586 +CFLAGS += -relax_pointers +#CFLAGS += -w on +ifeq ($(LIBARCH),LIBC) + PRELUDE = $(SDK_LIBC)/imports/libcpre.o + CFLAGS += -align 4 +else + # PRELUDE = $(SDK_CLIB)/imports/clibpre.o + # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK + PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj" + # CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h" + CFLAGS += -align 1 +endif +else +LD = nlmconv +LDFLAGS = -UT +AR = ar +ARFLAGS = -cq +LIBEXT = a +CFLAGS += -m32 +CFLAGS += -fno-builtin -fpcc-struct-return +CFLAGS += -fno-strict-aliasing +CFLAGS += -Wall # -pedantic +ifeq ($(LIBARCH),LIBC) + PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o +else + # PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o + # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK + # http://www.gknw.net/development/mk_nlm/gcc_pre.zip + PRELUDE = $(NDK_ROOT)/pre/prelude.o + CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h +endif +endif + +NDK_ROOT = $(NDKBASE)/ndk +SDK_CLIB = $(NDK_ROOT)/nwsdk +SDK_LIBC = $(NDK_ROOT)/libc +SNPRINTF = $(NDKBASE)/snprintf + +INCLUDES = -I.. -I../../include + +LDLIBS = + +ifdef LINK_STATIC + LDLIBS += ../libssh2.$(LIBEXT) +else + IMPORTS += @../libssh2.imp + MODULES += libssh2.nlm +endif + +INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L) +LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT) +LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT) +IMPORTS += GetProcessSwitchCount RunningProcess + +ifdef WITH_ZLIB + INCLUDES += -I$(ZLIB_PATH) +ifdef LINK_STATIC + LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT) +else + MODULES += libz.nlm + IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp +endif +endif + +ifeq ($(LIBARCH),LIBC) + INCLUDES += -I$(SDK_LIBC)/include + # INCLUDES += -I$(SDK_LIBC)/include/nks + # INCLUDES += -I$(SDK_LIBC)/include/winsock + CFLAGS += -D_POSIX_SOURCE +else + INCLUDES += -I$(SDK_CLIB)/include/nlm + # INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete + # INCLUDES += -I$(SDK_CLIB)/include + # CFLAGS += -DNETDB_USE_INTERNET +endif +CFLAGS += $(INCLUDES) + +ifeq ($(MTSAFE),YES) + XDCOPT = -n +endif +ifeq ($(MTSAFE),NO) + XDCOPT = -u +endif + +vpath %.c $(SAMPLES) + +.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc + + +all: prebuild $(TARGETS) + +prebuild: $(OBJDIR) $(OBJDIR)/version.inc + +$(OBJDIR)/%.o: %.c +# @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)/version.inc: ../../get_ver.awk ../../include/libssh2.h $(OBJDIR) + @echo Creating $@ + @$(AWK) -f $^ > $@ + +objclean: + $(call RMDIR, $(OBJDIR)) + +clean: objclean + $(foreach f, $(TARGETS), $(call DEL, $(f))) + +$(OBJDIR): + @$(call MKDIR, $@) + +%.nlm: $(OBJDIR)/%.def $(OBJDIR)/%.o $(OBJDIR)/%.xdc + @echo Linking $@ + @$(call DEL, $@) + @$(LD) $(LDFLAGS) $< + +$(OBJDIR)/%.xdc: GNUmakefile + @echo Creating $@ + @$(MPKXDC) $(XDCOPT) $@ + +$(OBJDIR)/%.def: GNUmakefile + @echo $(DL)# DEF file for linking with $(LD)$(DL) > $@ + @echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@ + @echo $(DL)# All your changes will be lost!!$(DL) >> $@ + @echo $(DL)#$(DL) >> $@ + @echo $(DL)copyright "$(COPYR)"$(DL) >> $@ + @echo $(DL)description "$(DESCR)"$(DL) >> $@ + @echo $(DL)version $(VERSION)$(DL) >> $@ +ifdef NLMTYPE + @echo $(DL)type $(NLMTYPE)$(DL) >> $@ +endif +ifdef STACK + @echo $(DL)stack $(STACK)$(DL) >> $@ +endif +ifdef SCREEN + @echo $(DL)screenname "$(SCREEN)"$(DL) >> $@ +else + @echo $(DL)screenname "DEFAULT"$(DL) >> $@ +endif +ifeq ($(DB),DEBUG) + @echo $(DL)debug$(DL) >> $@ +endif + @echo $(DL)threadname "$(notdir $(@:.def=))"$(DL) >> $@ +ifdef XDCOPT + @echo $(DL)xdcdata $(@:.def=.xdc)$(DL) >> $@ +endif +ifeq ($(LDRING),0) + @echo $(DL)flag_on 16$(DL) >> $@ +endif +ifeq ($(LDRING),3) + @echo $(DL)flag_on 512$(DL) >> $@ +endif +ifeq ($(LIBARCH),CLIB) + @echo $(DL)start _Prelude$(DL) >> $@ + @echo $(DL)exit _Stop$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/clib.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@ + @echo $(DL)module clib$(DL) >> $@ +else + @echo $(DL)flag_on 64$(DL) >> $@ + @echo $(DL)pseudopreemption$(DL) >> $@ + @echo $(DL)start _LibCPrelude$(DL) >> $@ + @echo $(DL)exit _LibCPostlude$(DL) >> $@ + @echo $(DL)check _LibCCheckUnload$(DL) >> $@ + @echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@ + @echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@ + @echo $(DL)module libc$(DL) >> $@ +endif +ifdef MODULES + @echo $(DL)module $(MODULES)$(DL) >> $@ +endif +ifdef EXPORTS + @echo $(DL)export $(EXPORTS)$(DL) >> $@ +endif +ifdef IMPORTS + @echo $(DL)import $(IMPORTS)$(DL) >> $@ +endif +ifeq ($(LD),nlmconv) + @echo $(DL)input $(@:.def=.o)$(DL) >> $@ + @echo $(DL)input $(PRELUDE)$(DL) >> $@ +ifdef LDLIBS + @echo $(DL)input $(LDLIBS)$(DL) >> $@ +endif + @echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@ +endif + diff --git a/libssh2/os400/README400 b/libssh2/os400/README400 new file mode 100644 index 000000000..fdac7da5b --- /dev/null +++ b/libssh2/os400/README400 @@ -0,0 +1,169 @@ + +Implementation notes: + + This is a true OS/400 implementation, not a PASE implementation (for PASE, +use AIX implementation). + +It uses ASCII as internal character set. This has been accomplished using the +QADRT library and include files, a C and system procedures ASCII wrapper +library. See IBM QADRT description for more information. + This results in libssh2 being an ASCII library: any function string +argument is taken/returned in ASCII and a C/C++ calling program built around +QADRT may use libssh2 functions as on any other platform. + QADRT does not define ASCII wrappers for all C/system procedures: an +additional module (os400sys.c) define some more of them, that are used by +libssh2 and that QADRT left out. + Since standard library entry points expect and return ASCII character strings, +additional procedures are provided for string transcoding (see below). No +wrappers to standard procedures are provided: however, nested calls to +transcoding procedures may be used. + +Crypto API is provided by the IBM QC3 API library. It supports RSA, but not DSA. + + + Standard compilation environment does support neither autotools nor make; +in fact, very few common utilities are available. As a consequence, the +libssh2_config.h has been coded manually and the compilation scripts are +a set of shell scripts stored in subdirectory os400. + + The test environment is currently not supported on OS/400. + + + +Compiling on OS/400: + + These instructions target people who knows about OS/400, compiling, IFS and +archive extraction. Do not ask questions about these subjects if you're not +familiar with. + +_ As a prerequisite, QADRT development environment must be installed. +_ Install the libssh2 sources directory in IFS. +_ Enter shell (QSH) +_ Change current directory to the libssh2 sources installation directory +_ Change current directory to os400 +_ Edit file iniscript.sh. You may want to change tunable configuration + parameters, like debug info generation, optimisation level, listing option, + target library, zlib availability and location, etc. +_ Copy any file in the current directory to makelog (i.e.: + cp initscript.sh makelog): this is intended to create the makelog file with + an ASCII CCSID! +_ Enter the command "sh make.sh > makelog 2>&1' +_ Examine the makelog file to check for compilation errors. + + Leaving file initscript.sh unchanged, this will produce the following OS/400 +objects: +_ Library LIBSSH2. All other objects will be stored in this library. +_ Modules for all libssh2 units. +_ Binding directory LIBSSH2_A, to be used at calling program link time for + statically binding the modules (specify BNDSRVPGM(QADRTTS) when creating a + program using LIBSSH2_A. Also give access to the zlib BNDDIR/SRVPGM if + libssh2 is compiled with zlib). +_ Service program LIBSSH2., where is extracted from the + src/Makefile.am VERSION variable. To be used at calling program run-time + when this program has dynamically bound libssh2 at link time. +_ Binding directory LIBSSH2. To be used to dynamically bind libssh2 when + linking a calling program. +_ Source file H. It contains all the include members needed to compile a C/C++ + module using libssh2. +_ LIBSSH2, SSH2_PKEY, SSH2_SFTP members in file H. These are the C/C++ header + files. Original fames have been mangled to fit member name allowed syntax. +_ Source file LIBSSH2RPG. It contains all the ILE/RPG /INCLUDE members + needed to compile an ILE/RPG program calling libssh2 procedures. +_ LIBSSH2, SSH2_PKEY, SSH2_SFTP members in file LIBSSH2RPG. These are + ILE/RPG translations of the corresponding C header files. + + + +Special programming consideration: + +QADRT being used, the following points must be considered: +_ If static binding is used, service program QADRTTS must be linked too. +_ Likewise, if libssh2 has been compiled with zlib support, access to the + zlib objects must be provided at link time. +_ The EBCDIC CCSID used by QADRT is 37 by default, NOT THE JOB'S CCSID. If + another EBCDIC CCSID is required, it must be set via a locale through a call + to setlocale_a (QADRT's setlocale() ASCII wrapper) with category LC_ALL or + LC_CTYPE, or by setting environment variable QADRT_ENV_LOCALE to the locale + object path before executing the program. +_ Do not use original source include files unless you know what you are doing. + Use the installed members instead (in /QSYS.LIB/LIBSSH2.LIB/H.FILE). + + + +String transcoding support: + + To help passing arbitrarily encoded string arguments and/or receiving string +values from/to the libssh2 API, three non-standard additional procedures are +provided. They use a session pointer and a "string cache" pointer. + Each time a string is transcoded, it is cached in the given cache. It is +the responsibility of the caller to release the cache when its associted strings +are no longer needed. These procedures and the string cache type are defined +in a new libssh2_ccsid.h header file. + To create a string cache, use: + +#include +libssh2_string_cache * cache = NULL; + + To release all strings in a cache, call: + +libssh2_release_string_cache(session, &cache); + + The transcoding procedures are: + +char * libssh2_from_ccsid(LIBSSH2_SESSION *session, + libssh2_string_cache **cache, + unsigned short ccsid, + const char *string, ssize_t inlen, + size_t *outlen); +char * libssh2_to_ccsid(LIBSSH2_SESSION *session, + libssh2_string_cache **cache, + unsigned short ccsid, + const char *string, ssize_t inlen, + size_t *outlen); + +where: + session is a libssh2 session used for memory allocation. + cache is the address of a string cache. + ccsid is the external (i.e.: non libssh2) coded character set id. + 65535 means no conversion and 0 means the current job's CCSID. + string is the string to convert. + inlen is the source string length in bytes: set to -1 if + null-terminated. + outlen if not NULL, is the address of a variable that will receive + the transcoded string length upon return. + + libssh2_from_ccsid() transcodes the string from the given CCSID to libssh2 +internal encoding (UTF-8). It is intended to be used to convert API input +parameters. + libssh2_to_ccsid() transcodes the string from libssh2 internal encoding +(UTF-8) to the given CCSID. This has been implemented to get standard API +string results in a program's native encoding. + + Both these functions return a pointer to the null-terminated converted string, +or NULL if an error occurred. In addition, the variable pointed by outlen +receives the effective byte length of the (cached) translated string, or -1 +in case of error. + + + +ILE/RPG support: + + Since 95% of the OS/400 programmers use ILE/RPG exclusively, a definition + /INCLUDE member is provided for this language. To include libssh2 + definitions in an ILE/RPG module, line + + h bnddir('LIBSSH2/LIBSSH2') + +must figure in the program header, and line + + d/include libssh2/libssh2rpg,libssh2 + +in the global data section of the module's source code. +If required, members ssh2_sftp, ssh2_pkey and ssh2_ccsid may also be included. + +For IFS source compilations, include members are located in directory +/libssh2/include/libssh2rpg and have their original names retained. + +ILE/RPG lacks a serious macro preprocessor, thus C macros requiring this +feature have not been translated. However, function-like C macros have been +implemented as procedures and therefore supported in ILE/RPG. diff --git a/libssh2/os400/ccsid.c b/libssh2/os400/ccsid.c new file mode 100644 index 000000000..ef02f1d30 --- /dev/null +++ b/libssh2/os400/ccsid.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +/* Character encoding wrappers. */ + +#include "libssh2_priv.h" +#include "libssh2_ccsid.h" + +#include +#include +#include +#include +#include + + + +#define CCSID_UTF8 1208 +#define CCSID_UTF16BE 13488 +#define STRING_GRANULE 256 +#define MAX_CHAR_SIZE 4 + +#define OFFSET_OF(t, f) ((size_t) ((char *) &((t *) 0)->f - (char *) 0)) + + +struct _libssh2_string_cache { + libssh2_string_cache * next; + char string[1]; +}; + + +static const QtqCode_T utf8code = { CCSID_UTF8 }; + + +static ssize_t +terminator_size(unsigned short ccsid) +{ + QtqCode_T outcode; + iconv_t cd; + char *inp; + char *outp; + size_t ilen; + size_t olen; + char buf[MAX_CHAR_SIZE]; + + /* Return the null-terminator size for the given CCSID. */ + + /* Fast check usual CCSIDs. */ + switch (ccsid) { + case CCSID_UTF8: + case 0: /* Job CCSID is SBCS EBCDIC. */ + return 1; + case CCSID_UTF16BE: + return 2; + } + + /* Convert an UTF-8 NUL to the target CCSID: use the converted size as + result. */ + memset((void *) &outcode, 0, sizeof outcode); + outcode.CCSID = ccsid; + cd = QtqIconvOpen(&outcode, (QtqCode_T *) &utf8code); + if (cd.return_value == -1) + return -1; + inp = ""; + ilen = 1; + outp = buf; + olen = sizeof buf; + iconv(cd, &inp, &ilen, &outp, &olen); + iconv_close(cd); + olen = sizeof buf - olen; + return olen? olen: -1; +} + +static char * +convert_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache, + unsigned short outccsid, unsigned short inccsid, + const char *instring, ssize_t inlen, size_t *outlen) +{ + char *inp; + char *outp; + size_t olen; + size_t ilen; + size_t buflen; + size_t curlen; + ssize_t termsize; + int i; + char *dst; + libssh2_string_cache *outstring; + QtqCode_T incode; + QtqCode_T outcode; + iconv_t cd; + + if (!instring) { + if (outlen) + *outlen = 0; + return NULL; + } + if (outlen) + *outlen = -1; + if (!session || !cache) + return NULL; + + /* Get terminator size. */ + termsize = terminator_size(outccsid); + if (termsize < 0) + return NULL; + + /* Prepare conversion parameters. */ + memset((void *) &incode, 0, sizeof incode); + memset((void *) &outcode, 0, sizeof outcode); + incode.CCSID = inccsid; + outcode.CCSID = outccsid; + curlen = OFFSET_OF(libssh2_string_cache, string); + inp = (char *) instring; + ilen = inlen; + buflen = inlen + curlen; + if (inlen < 0) { + incode.length_option = 1; + buflen = STRING_GRANULE; + ilen = 0; + } + + /* Allocate output string buffer and open conversion descriptor. */ + dst = LIBSSH2_ALLOC(session, buflen + termsize); + if (!dst) + return NULL; + cd = QtqIconvOpen(&outcode, &incode); + if (cd.return_value == -1) { + LIBSSH2_FREE(session, (char *) dst); + return NULL; + } + + /* Convert string. */ + for (;;) { + outp = dst + curlen; + olen = buflen - curlen; + i = iconv(cd, &inp, &ilen, &outp, &olen); + if (inlen < 0 && olen == buflen - curlen) { + /* Special case: converted 0-length (sub)strings do not store the + terminator. */ + if (termsize) { + memset(outp, 0, termsize); + olen -= termsize; + } + } + curlen = buflen - olen; + if (i >= 0 || errno != E2BIG) + break; + /* Must expand buffer. */ + buflen += STRING_GRANULE; + outp = LIBSSH2_REALLOC(session, dst, buflen + termsize); + if (!outp) + break; + dst = outp; + } + + iconv_close(cd); + + /* Check for error. */ + if (i < 0 || !outp) { + LIBSSH2_FREE(session, dst); + return NULL; + } + + /* Process terminator. */ + if (inlen < 0) + curlen -= termsize; + else if (termsize) + memset(dst + curlen, 0, termsize); + + /* Shorten buffer if possible. */ + if (curlen < buflen) + dst = LIBSSH2_REALLOC(session, dst, curlen + termsize); + + /* Link to cache. */ + outstring = (libssh2_string_cache *) dst; + outstring->next = *cache; + *cache = outstring; + + /* Return length if required. */ + if (outlen) + *outlen = curlen - OFFSET_OF(libssh2_string_cache, string); + + return outstring->string; +} + +LIBSSH2_API char * +libssh2_from_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache, + unsigned short ccsid, const char *string, ssize_t inlen, + size_t *outlen) +{ + return convert_ccsid(session, cache, + CCSID_UTF8, ccsid, string, inlen, outlen); +} + +LIBSSH2_API char * +libssh2_to_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache, + unsigned short ccsid, const char *string, ssize_t inlen, + size_t *outlen) +{ + return convert_ccsid(session, cache, + ccsid, CCSID_UTF8, string, inlen, outlen); +} + +LIBSSH2_API void +libssh2_release_string_cache(LIBSSH2_SESSION *session, + libssh2_string_cache **cache) +{ + libssh2_string_cache *p; + + if (session && cache) + while ((p = *cache)) { + *cache = p->next; + LIBSSH2_FREE(session, (char *) p); + } +} + +/* vim: set expandtab ts=4 sw=4: */ diff --git a/libssh2/os400/include/alloca.h b/libssh2/os400/include/alloca.h new file mode 100644 index 000000000..ff0cee4e2 --- /dev/null +++ b/libssh2/os400/include/alloca.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBSSH2_ALLOCA_H +#define LIBSSH2_ALLOCA_H + +/* alloca() emulation. */ + +#include + +#define alloca(n) _MODASA(n) + +#endif + +/* vim: set expandtab ts=4 sw=4: */ diff --git a/libssh2/os400/include/stdio.h b/libssh2/os400/include/stdio.h new file mode 100644 index 000000000..7ac9d9938 --- /dev/null +++ b/libssh2/os400/include/stdio.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBSSH2_STDIO_H +#define LIBSSH2_STDIO_H + +/* + * wrapper. + * Its goal is to redefine snprintf/vsnprintf which are not supported by QADRT. + */ + +#include + +#if __ILEC400_TGTVRM__ >= 710 +# include_next +#elif __ILEC400_TGTVRM__ >= 510 +# ifndef __SRCSTMF__ +# include +# else +# include +# endif +#endif + +extern int _libssh2_os400_vsnprintf(char *dst, size_t len, + const char *fmt, va_list args); +extern int _libssh2_os400_snprintf(char *dst, size_t len, + const char *fmt, ...); + +#ifndef LIBSSH2_DISABLE_QADRT_EXT +# define vsnprintf(dst, len, fmt, args) \ + _libssh2_os400_vsnprintf((dst), (len), (fmt), (args)) +# define snprintf _libssh2_os400_snprintf +#endif + +#endif + +/* vim: set expandtab ts=4 sw=4: */ diff --git a/libssh2/os400/include/sys/socket.h b/libssh2/os400/include/sys/socket.h new file mode 100644 index 000000000..4c7712186 --- /dev/null +++ b/libssh2/os400/include/sys/socket.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBSSH2_SYS_SOCKET_H +#define LIBSSH2_SYS_SOCKET_H + +/* + * wrapper. + * Redefines connect(). + */ + +#include + +#ifndef _QADRT_LT +# define _QADRT_LT < +#endif +#ifndef _QADRT_GT +# define _QADRT_GT > +#endif + +#ifdef QADRT_SYSINC +# include _QADRT_LT QADRT_SYSINC/sys/socket.h _QADRT_GT +#elif __ILEC400_TGTVRM__ >= 710 +# include_next +#elif !defined(__SRCSTMF__) +# include +#else +# include +#endif + +extern int _libssh2_os400_connect(int sd, + struct sockaddr * destaddr, int addrlen); + +#ifndef LIBSSH2_DISABLE_QADRT_EXT +#define connect(sd, addr, len) _libssh2_os400_connect((sd), (addr), (len)) +#endif + +#endif + +/* vim: set expandtab ts=4 sw=4: */ diff --git a/libssh2/os400/initscript.sh b/libssh2/os400/initscript.sh new file mode 100644 index 000000000..1d47a1dd8 --- /dev/null +++ b/libssh2/os400/initscript.sh @@ -0,0 +1,243 @@ +#!/bin/sh + + +setenv() + +{ + # Define and export. + + eval ${1}="${2}" + export ${1} +} + + +case "${SCRIPTDIR}" in +/*) ;; +*) SCRIPTDIR="`pwd`/${SCRIPTDIR}" +esac + +while true +do case "${SCRIPTDIR}" in + */.) SCRIPTDIR="${SCRIPTDIR%/.}";; + *) break;; + esac +done + +# The script directory is supposed to be in $TOPDIR/os400. + +TOPDIR=`dirname "${SCRIPTDIR}"` +export SCRIPTDIR TOPDIR + +# Extract the SONAME from the library makefile. + +SONAME=`sed -e '/^VERSION=/!d' -e 's/^.* \([0-9]*\):.*$/\1/' -e 'q' \ + < "${TOPDIR}/src/Makefile.am"` +export SONAME + + +################################################################################ +# +# Tunable configuration parameters. +# +################################################################################ + +setenv TARGETLIB 'LIBSSH2' # Target OS/400 program library. +setenv STATBNDDIR 'LIBSSH2_A' # Static binding directory. +setenv DYNBNDDIR 'LIBSSH2' # Dynamic binding directory. +setenv SRVPGM "LIBSSH2.${SONAME}" # Service program. +setenv TGTCCSID '500' # Target CCSID of objects. +setenv DEBUG '*ALL' # Debug level. +setenv OPTIMIZE '10' # Optimisation level +setenv OUTPUT '*NONE' # Compilation output option. +setenv TGTRLS 'V5R3M0' # Target OS release. +setenv IFSDIR '/libssh2' # Installation IFS directory. + +# Define ZLIB availability and locations. + +setenv WITH_ZLIB 0 # Define to 1 to enable. +setenv ZLIB_INCLUDE '/zlib/include' # ZLIB include IFS directory. +setenv ZLIB_LIB 'ZLIB' # ZLIB library. +setenv ZLIB_BNDDIR 'ZLIB_A' # ZLIB binding directory. + + +################################################################################ + +# Need to get the version definitions. + +LIBSSH2_VERSION=`grep '^#define *LIBSSH2_VERSION ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/.*"\(.*\)".*/\1/'` +LIBSSH2_VERSION_MAJOR=`grep '^#define *LIBSSH2_VERSION_MAJOR ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/^#define *LIBSSH2_VERSION_MAJOR *\([^ ]*\).*/\1/'` +LIBSSH2_VERSION_MINOR=`grep '^#define *LIBSSH2_VERSION_MINOR ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/^#define *LIBSSH2_VERSION_MINOR *\([^ ]*\).*/\1/'` +LIBSSH2_VERSION_PATCH=`grep '^#define *LIBSSH2_VERSION_PATCH ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/^#define *LIBSSH2_VERSION_PATCH *\([^ ]*\).*/\1/'` +LIBSSH2_VERSION_NUM=`grep '^#define *LIBSSH2_VERSION_NUM ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/^#define *LIBSSH2_VERSION_NUM *0x\([^ ]*\).*/\1/'` +LIBSSH2_TIMESTAMP=`grep '^#define *LIBSSH2_TIMESTAMP ' \ + "${TOPDIR}/include/libssh2.h" | + sed 's/.*"\(.*\)".*/\1/'` +export LIBSSH2_VERSION +export LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH +export LIBSSH2_VERSION_NUM LIBSSH2_TIMESTAMP + +################################################################################ +# +# OS/400 specific definitions. +# +################################################################################ + +LIBIFSNAME="/QSYS.LIB/${TARGETLIB}.LIB" + + +################################################################################ +# +# Procedures. +# +################################################################################ + +# action_needed dest [src] +# +# dest is an object to build +# if specified, src is an object on which dest depends. +# +# exit 0 (succeeds) if some action has to be taken, else 1. + +action_needed() + +{ + [ ! -e "${1}" ] && return 0 + [ "${2}" ] || return 1 + [ "${1}" -ot "${2}" ] && return 0 + return 1 +} + + +# canonicalize_path path +# +# Return canonicalized path as: +# - Absolute +# - No . or .. component. + +canonicalize_path() + +{ + if expr "${1}" : '^/' > /dev/null + then P="${1}" + else P="`pwd`/${1}" + fi + + R= + IFSSAVE="${IFS}" + IFS="/" + + for C in ${P} + do IFS="${IFSSAVE}" + case "${C}" in + .) ;; + ..) R=`expr "${R}" : '^\(.*/\)..*'` + ;; + ?*) R="${R}${C}/" + ;; + *) ;; + esac + done + + IFS="${IFSSAVE}" + echo "/`expr "${R}" : '^\(.*\)/'`" +} + + +# make_module module_name source_name [additional_definitions] +# +# Compile source name into ASCII module if needed. +# As side effect, append the module name to variable MODULES. +# Set LINK to "YES" if the module has been compiled. + +make_module() + +{ + MODULES="${MODULES} ${1}" + MODIFSNAME="${LIBIFSNAME}/${1}.MODULE" + action_needed "${MODIFSNAME}" "${2}" || return 0; + SRCDIR=`dirname \`canonicalize_path "${2}"\`` + + # #pragma convert has to be in the source file itself, i.e. + # putting it in an include file makes it only active + # for that include file. + # Thus we build a temporary file with the pragma prepended to + # the source file and we compile that temporary file. + + echo "#line 1 \"${2}\"" > __tmpsrcf.c + echo "#pragma convert(819)" >> __tmpsrcf.c + echo "#line 1" >> __tmpsrcf.c + cat "${2}" >> __tmpsrcf.c + CMD="CRTCMOD MODULE(${TARGETLIB}/${1}) SRCSTMF('__tmpsrcf.c')" +# CMD="${CMD} SYSIFCOPT(*IFS64IO) OPTION(*INCDIRFIRST *SHOWINC *SHOWSYS)" + CMD="${CMD} SYSIFCOPT(*IFS64IO) OPTION(*INCDIRFIRST)" + CMD="${CMD} LOCALETYPE(*LOCALE)" + CMD="${CMD} INCDIR('${TOPDIR}/os400/include'" + CMD="${CMD} '/QIBM/ProdData/qadrt/include' '${TOPDIR}/include'" + CMD="${CMD} '${TOPDIR}/os400' '${SRCDIR}'" + + if [ "${WITH_ZLIB}" != "0" ] + then CMD="${CMD} '${ZLIB_INCLUDE}'" + fi + + CMD="${CMD} ${INCLUDES})" + CMD="${CMD} TGTCCSID(${TGTCCSID}) TGTRLS(${TGTRLS})" + CMD="${CMD} OUTPUT(${OUTPUT})" + CMD="${CMD} OPTIMIZE(${OPTIMIZE})" + CMD="${CMD} DBGVIEW(${DEBUG})" + + DEFINES="${3}" + + if [ "${WITH_ZLIB}" != "0" ] + then DEFINES="${DEFINES} HAVE_LIBZ LIBSSH2_HAVE_ZLIB" + fi + + if [ "${DEFINES}" ] + then CMD="${CMD} DEFINE(${DEFINES})" + fi + + system "${CMD}" + rm -f __tmpsrcf.c + LINK=YES +} + + +# Determine DB2 object name from IFS name. + +db2_name() + +{ + if [ "${2}" = 'nomangle' ] + then basename "${1}" | + tr 'a-z-' 'A-Z_' | + sed -e 's/\..*//;s/^\(.\).*\(.........\)$/\1\2/' + else basename "${1}" | + tr 'a-z-' 'A-Z_' | + sed -e 's/\..*//;s/^LIBSSH2_/SSH2_/' \ + -e 's/^\(.\).*\(.........\)$/\1\2/' \ + -e 's/^SPUBLICKEY$/SSH2_PKEY/' + fi +} + + +# Copy stream replacing version info. + +versioned_copy() + +{ + sed -e "s/@LIBSSH2_VERSION@/${LIBSSH2_VERSION}/g" \ + -e "s/@LIBSSH2_VERSION_MAJOR@/${LIBSSH2_VERSION_MAJOR}/g" \ + -e "s/@LIBSSH2_VERSION_MINOR@/${LIBSSH2_VERSION_MINOR}/g" \ + -e "s/@LIBSSH2_VERSION_PATCH@/${LIBSSH2_VERSION_PATCH}/g" \ + -e "s/@LIBSSH2_VERSION_NUM@/${LIBSSH2_VERSION_NUM}/g" \ + -e "s/@LIBSSH2_TIMESTAMP@/${LIBSSH2_TIMESTAMP}/g" +} diff --git a/libssh2/os400/libssh2_ccsid.h b/libssh2/os400/libssh2_ccsid.h new file mode 100644 index 000000000..632effa38 --- /dev/null +++ b/libssh2/os400/libssh2_ccsid.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +/* CCSID conversion support. */ + +#ifndef LIBSSH2_CCSID_H_ +#define LIBSSH2_CCSID_H_ + +#include "libssh2.h" + +typedef struct _libssh2_string_cache libssh2_string_cache; + + +LIBSSH2_API char * +libssh2_from_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache, + unsigned short ccsid, const char *string, ssize_t inlen, + size_t *outlen); +LIBSSH2_API char * +libssh2_to_ccsid(LIBSSH2_SESSION *session, libssh2_string_cache **cache, + unsigned short ccsid, const char *string, ssize_t inlen, + size_t *outlen); +LIBSSH2_API void +libssh2_release_string_cache(LIBSSH2_SESSION *session, + libssh2_string_cache **cache); + +#endif + +/* vim: set expandtab ts=4 sw=4: */ diff --git a/libssh2/os400/libssh2_config.h b/libssh2/os400/libssh2_config.h new file mode 100644 index 000000000..2e34c4c37 --- /dev/null +++ b/libssh2/os400/libssh2_config.h @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBSSH2_CONFIG_H +#define LIBSSH2_CONFIG_H + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. +*/ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the declaration of `SecureZeroMemory', and to 0 if + you don't. */ +#undef HAVE_DECL_SECUREZEROMEMORY + +/* disabled non-blocking sockets */ +#undef HAVE_DISABLED_NONBLOCKING + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `EVP_aes_128_ctr' function. */ +#undef HAVE_EVP_AES_128_CTR + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* use FIONBIO for non-blocking sockets */ +#undef HAVE_FIONBIO + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* use ioctlsocket() for non-blocking sockets */ +#undef HAVE_IOCTLSOCKET + +/* use Ioctlsocket() for non-blocking sockets */ +#undef HAVE_IOCTLSOCKET_CASE + +/* Define if you have the bcrypt library. */ +#undef HAVE_LIBBCRYPT + +/* Define if you have the crypt32 library. */ +#undef HAVE_LIBCRYPT32 + +/* Define if you have the gcrypt library. */ +#undef HAVE_LIBGCRYPT + +/* Define if you have the ssl library. */ +#undef HAVE_LIBSSL + +/* Define if you have the z library. */ +/* #undef HAVE_LIBZ */ + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#define HAVE_LONGLONG 1 + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#undef HAVE_NTDEF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NTSTATUS_H + +/* use O_NONBLOCK for non-blocking sockets */ +#define HAVE_O_NONBLOCK 1 + +/* Define to 1 if you have the `poll' function. */ +#undef HAVE_POLL + +/* Define to 1 if you have the select function. */ +#define HAVE_SELECT 1 + +/* use SO_NONBLOCK for non-blocking sockets */ +#undef HAVE_SO_NONBLOCK + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define HAVE_STRTOLL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINSOCK2_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WS2TCPIP_H + +/* to make a symbol visible */ +#undef LIBSSH2_API + +/* Enable clearing of memory before being freed */ +#define LIBSSH2_CLEAR_MEMORY 1 + +/* Enable "none" cipher -- NOT RECOMMENDED */ +#undef LIBSSH2_CRYPT_NONE + +/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ +#define LIBSSH2_DH_GEX_NEW 1 + +/* Compile in zlib support */ +/* #undef LIBSSH2_HAVE_ZLIB */ + +/* Use libgcrypt */ +#undef LIBSSH2_LIBGCRYPT + +/* Enable "none" MAC -- NOT RECOMMENDED */ +#undef LIBSSH2_MAC_NONE + +/* Use OpenSSL */ +#undef LIBSSH2_OPENSSL + +/* Use Windows CNG */ +#undef LIBSSH2_WINCNG + +/* Use OS/400 Qc3 */ +#define LIBSSH2_OS400QC3 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. +*/ +#define LT_OBJDIR ".libs/" + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +#undef NEED_REENTRANT + +/* Name of package */ +#define PACKAGE "libssh2" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "libssh2-devel@cool.haxx.se" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libssh2" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libssh2 -" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libssh2" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "-" + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "-" + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#define WORDS_BIGENDIAN 1 + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#define inline +#endif + +/* Define to `unsigned int' if does not define. */ +#undef size_t + + +#ifndef LIBSSH2_DISABLE_QADRT_EXT +/* Remap zlib procedures to ASCII versions. */ +#pragma map(inflateInit_, "_libssh2_os400_inflateInit_") +#pragma map(deflateInit_, "_libssh2_os400_deflateInit_") +#endif + +#endif +/* vim: set expandtab ts=4 sw=4: */ diff --git a/libssh2/os400/libssh2rpg/libssh2.rpgle.in b/libssh2/os400/libssh2rpg/libssh2.rpgle.in new file mode 100644 index 000000000..7b7fdd946 --- /dev/null +++ b/libssh2/os400/libssh2rpg/libssh2.rpgle.in @@ -0,0 +1,1704 @@ + * Copyright (c) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + + /if not defined(LIBSSH2_H_) + /define LIBSSH2_H_ + + d LIBSSH2_COPYRIGHT... + d c '2004-2015 The libssh2 project and + + d its contributors.' + + * We use underscore instead of dash when appending DEV in dev versions + * just to make the BANNER define (used by src/session.c) be a valid SSH + * banner. Release versions have no appended strings and may of course not + * have dashes either. + d LIBSSH2_VERSION... + d c '@LIBSSH2_VERSION@' + + * The numeric version number is also available "in parts" by using these + * defines: + d LIBSSH2_VERSION_MAJOR... + d c @LIBSSH2_VERSION_MAJOR@ + d LIBSSH2_VERSION_MINOR... + d c @LIBSSH2_VERSION_MINOR@ + d LIBSSH2_VERSION_PATCH... + d c @LIBSSH2_VERSION_PATCH@ + + * This is the numeric version of the libssh2 version number, meant for + * easier parsing and comparions by programs. The LIBSSH2_VERSION_NUM + * define will always follow this syntax: + * + * X'XXYYZZ' + * + * Where XX, YY and ZZ are the main version, release and patch numbers in + * hexadecimal (using 8 bits each). All three numbers are always + * represented using two digits. 1.2 would appear as "0x010200" while + * version 9.11.7 appears as X'090b07'. + * + * This 6-digit (24 bits) hexadecimal number does not show pre-release + * number, and it is always a greater number in a more recent release. It + * makes comparisons with greater than and less than work. + + d LIBSSH2_VERSION_NUM... + d c X'@LIBSSH2_VERSION_NUM@' + + * This is the date and time when the full source package was created. The + * timestamp is not stored in the source code repo, as the timestamp is + * properly set in the tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + + d LIBSSH2_TIMESTAMP... + d c '@LIBSSH2_TIMESTAMP@' + + d libssh2_Cchar s 3i 0 based(######typedef######) + d libssh2_Cuchar s 3u 0 based(######typedef######) + d libssh2_Cshort s 5i 0 based(######typedef######) + d libssh2_Cushort... + d s 5u 0 based(######typedef######) + d libssh2_Cint s 10i 0 based(######typedef######) + d libssh2_CuInt s 10u 0 based(######typedef######) + d libssh2_Clong s 10i 0 based(######typedef######) + d libssh2_Culong s 10u 0 based(######typedef######) + d libssh2_Clonglong... + d s 20i 0 based(######typedef######) + d libssh2_Culonglong... + d s 20u 0 based(######typedef######) + d libssh2_Cenum s 10i 0 based(######typedef######) + d libssh2_Cssize_t... + d s 10i 0 based(######typedef######) + d libssh2_Csize_t... + d s 10u 0 based(######typedef######) + d libssh2_Cfloat s 4f based(######typedef######) + d libssh2_Cdouble... + d s 8f based(######typedef######) + + d libssh2_uint8_t... + d s 3u 0 based(######typedef######) + d libssh2_uint32_t... + d s 10u 0 based(######typedef######) + d libssh2_uint64_t... + d s 20u 0 based(######typedef######) + d libssh2_int64_t... + d s 20i 0 based(######typedef######) + + d libssh2_socket_t... + d s 10i 0 based(######typedef######) + d LIBSSH2_INVALID_SOCKET... + d c -1 + + d libssh2_mode_t s 10u 0 based(######typedef######) + d libssh2_ino_t s 10u 0 based(######typedef######) + d libssh2_uid_t s 10u 0 based(######typedef######) + d libssh2_gid_t s 10u 0 based(######typedef######) + d libssh2_dev_t s 10u 0 based(######typedef######) + d libssh2_off_t s 20i 0 based(######typedef######) Use *IFS64IO + d libssh2_time_t s 10i 0 based(######typedef######) + d libssh2_nlink_t... + d s 5u 0 based(######typedef######) + d libssh2_qp0l_objtype_t... AS400 object type + d s 11 + + d libssh2_struct_stat_size... + d s based(######typedef######) + d like(libssh2_off_t) + + d libssh2_struct_stat... + d ds based(######typedef######) + d align qualified + d st_mode like(libssh2_mode_t) Mode flags + d st_ino like(libssh2_ino_t) File serial number + d st_nlink like(libssh2_nlink_t) Number of links + d st_uid like(libssh2_uid_t) Owner ID + d st_gid like(libssh2_gid_t) Group ID + d st_size like(libssh2_off_t) File size + d st_atime like(libssh2_time_t) Last access time + d st_mtime like(libssh2_time_t) Last update time + d st_ctime like(libssh2_time_t) Creation time + d st_dev like(libssh2_dev_t) File root device + d st_blksize like(libssh2_Csize_t) Block size + d st_allocsize like(libssh2_Culong) Allocation size + d st_objtype like(libssh2_qp0l_objtype_t) AS400 object type + d st_codepage like(libssh2_Cushort) Object data codepage + d 62 Reserved + d st_ino_gen_id like(libssh2_Cuint) File SN gen. ID + + d LIBSSH2_STRUCT_STAT_SIZE_FORMAT... + d c '%lld' + + * Part of every banner, user specified or not. + d LIBSSH2_SSH_BANNER... + d c 'SSH-2.0-libssh2_1.6.1_DEV' + d LIBSSH2_SSH_DEFAULT_BANNER... + d c 'SSH-2.0-libssh2_1.6.1_DEV' + + * Default generate and safe prime sizes for + * diffie-hellman-group-exchange-sha1. + d LIBSSH2_DH_GEX_MINGROUP... + d c 1024 + d LIBSSH2_DH_GEX_OPTGROUP... + d c 1536 + d LIBSSH2_DH_GEX_MAXGROUP... + d c 2048 + + * Defaults for pty requests. + d LIBSSH2_TERM_WIDTH... + d c 80 + d LIBSSH2_TERM_HEIGHT... + d c 24 + d LIBSSH2_TERM_WIDTH_PX... + d c 0 + d LIBSSH2_TERM_HEIGHT_PX... + d c 0 + + * 1/4 second. + d LIBSSH2_SOCKET_POLL_UDELAY... + d c 250000 + * 0.25 * 120 == 30 seconds. + d LIBSSH2_SOCKET_POLL_MAXLOOPS... + d c 120 + + * Maximum size to allow a payload to compress to, plays it safe by + * falling short of spec limits. + d LIBSSH2_PACKET_MAXCOMP... + d c 32000 + + * Maximum size to allow a payload to deccompress to, plays it safe by + * allowing more than spec requires. + d LIBSSH2_PACKET_MAXDECOMP... + d c 40000 + + * Maximum size for an inbound compressed payload, plays it safe by + * overshooting spec limits. + d LIBSSH2_PACKET_MAXPAYLOAD... + d c 40000 + + d LIBSSH2_USERAUTH_KBDINT_PROMPT... + d ds based(######typedef######) + d align qualified + d text * char * + d length like(libssh2_Cuint) + d echo like(libssh2_Cuchar) + + d LIBSSH2_USERAUTH_KBDINT_RESPONSE... + d ds based(######typedef######) + d align qualified + d text * char * + d length like(libssh2_Cuint) + + * libssh2_session_callback_set() constants. + d LIBSSH2_CALLBACK_IGNORE... + d c 0 + d LIBSSH2_CALLBACK_DEBUG... + d c 1 + d LIBSSH2_CALLBACK_DISCONNECT... + d c 2 + d LIBSSH2_CALLBACK_MACERROR... + d c 3 + d LIBSSH2_CALLBACK_X11... + d c 4 + d LIBSSH2_CALLBACK_SEND... + d c 5 + d LIBSSH2_CALLBACK_RECV... + d c 6 + + * libssh2_session_method_pref() constants. + d LIBSSH2_METHOD_KEX... + d c 0 + d LIBSSH2_METHOD_HOSTKEY... + d c 1 + d LIBSSH2_METHOD_CRYPT_CS... + d c 2 + d LIBSSH2_METHOD_CRYPT_SC... + d c 3 + d LIBSSH2_METHOD_MAC_CS... + d c 4 + d LIBSSH2_METHOD_MAC_SC... + d c 5 + d LIBSSH2_METHOD_COMP_CS... + d c 6 + d LIBSSH2_METHOD_COMP_SC... + d c 7 + d LIBSSH2_METHOD_LANG_CS... + d c 8 + d LIBSSH2_METHOD_LANG_SC... + d c 9 + + * flags. + d LIBSSH2_FLAG_SIGPIPE... + d c X'0001' + d LIBSSH2_FLAG_COMPRESS... + d c X'0002' + + d LIBSSH2_POLLFD ds based(######typedef######) + d align qualified + d type like(libssh2_Cuchar) + d fd * Union + d socket overlay(fd) like(libssh2_socket_t) + d channel * overlay(fd) LIBSSH2_CHANNEL * + d listener * overlay(fd) LIBSSH2_LISTENER * + d events like(libssh2_Culong) + d revents like(libssh2_Culong) + + * Poll FD Descriptor Types. + d LIBSSH2_POLLFD_SOCKET... + d c 1 + d LIBSSH2_POLLFD_CHANNEL... + d c 2 + d LIBSSH2_POLLFD_LISTENER... + d c 3 + + * Poll FD events/revents -- Match sys/poll.h where possible. + d LIBSSH2_POLLFD_POLLIN... Input data ready or + d c X'0001' connection available + d LIBSSH2_POLLFD_POLLPRI... Prio data ready to + d c X'0002' be read. Socket only + d LIBSSH2_POLLFD_POLLEXT... Ext data ready to be + d c X'0002' read. Channel only + d LIBSSH2_POLLFD_POLLOUT... Can may be written: + d c X'0004' Socket/Channel + + * revents only. + d LIBSSH2_POLLFD_POLLERR... Error Condition: + d c X'0008' Socket + d LIBSSH2_POLLFD_POLLHUP... HangUp/EOF + d c X'0010' Socket + d LIBSSH2_POLLFD_SESSION_CLOSED... Session Disconnect + d c X'0010' + d LIBSSH2_POLLFD_POLLNVAL... Invalid request + d c X'0020' Socket + d LIBSSH2_POLLFD_POLLEX... Exception Condition + d c X'0040' Socket/Win32 + d LIBSSH2_POLLFD_CHANNEL_CLOSED... Channel Disconnect + d c X'0080' + d LIBSSH2_POLLFD_LISTENER_CLOSED... Listener Disconnect + d c X'0080' + + /define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION + * Block Direction Types. + d LIBSSH2_SESSION_BLOCK_INBOUND... + d c X'0001' + d LIBSSH2_SESSION_BLOCK_OUTBOUND... + d c X'0002' + + * Hash Types. + d LIBSSH2_HOSTKEY_HASH_MD5... + d c 1 + d LIBSSH2_HOSTKEY_HASH_SHA1... + d c 2 + + * Hostkey Types. + d LIBSSH2_HOSTKEY_TYPE_UNKNOWN... + d c 0 + d LIBSSH2_HOSTKEY_TYPE_RSA... + d c 1 + d LIBSSH2_HOSTKEY_TYPE_DSS... + d c 2 + + * Disconnect Codes (defined by SSH protocol). + d SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT... + d c 1 + d SSH_DISCONNECT_PROTOCOL_ERROR... + d c 2 + d SSH_DISCONNECT_KEY_EXCHANGE_FAILED... + d c 3 + d SSH_DISCONNECT_RESERVED... + d c 4 + d SSH_DISCONNECT_MAC_ERROR... + d c 5 + d SSH_DISCONNECT_COMPRESSION_ERROR... + d c 6 + d SSH_DISCONNECT_SERVICE_NOT_AVAILABLE... + d c 7 + d SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED... + d c 8 + d SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE... + d c 9 + d SSH_DISCONNECT_CONNECTION_LOST... + d c 10 + d SSH_DISCONNECT_BY_APPLICATION... + d c 11 + d SSH_DISCONNECT_TOO_MANY_CONNECTIONS... + d c 12 + d SSH_DISCONNECT_AUTH_CANCELLED_BY_USER... + d c 13 + d SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE... + d c 14 + d SSH_DISCONNECT_ILLEGAL_USER_NAME... + d c 15 + + * Error Codes (defined by libssh2). + d LIBSSH2_ERROR_NONE... + d c 0 + + * The library once used -1 as a generic error return value on numerous + * places through the code, which subsequently was converted to + * LIBSSH2_ERROR_SOCKET_NONE uses over time. As this is a generic error + * code, the goal is to never ever return this code but instead make sure + * that a more accurate and descriptive error code is used. + d LIBSSH2_ERROR_SOCKET_NONE... + d c -1 + + d LIBSSH2_ERROR_BANNER_RECV... + d c -2 + d LIBSSH2_ERROR_BANNER_SEND... + d c -3 + d LIBSSH2_ERROR_INVALID_MAC... + d c -4 + d LIBSSH2_ERROR_KEX_FAILURE... + d c -5 + d LIBSSH2_ERROR_ALLOC... + d c -6 + d LIBSSH2_ERROR_SOCKET_SEND... + d c -7 + d LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE... + d c -8 + d LIBSSH2_ERROR_TIMEOUT... + d c -9 + d LIBSSH2_ERROR_HOSTKEY_INIT... + d c -10 + d LIBSSH2_ERROR_HOSTKEY_SIGN... + d c -11 + d LIBSSH2_ERROR_DECRYPT... + d c -12 + d LIBSSH2_ERROR_SOCKET_DISCONNECT... + d c -13 + d LIBSSH2_ERROR_PROTO... + d c -14 + d LIBSSH2_ERROR_PASSWORD_EXPIRED... + d c -15 + d LIBSSH2_ERROR_FILE... + d c -16 + d LIBSSH2_ERROR_METHOD_NONE... + d c -17 + d LIBSSH2_ERROR_AUTHENTICATION_FAILED... + d c -18 + d LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED... + d c -18 + d LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED... + d c -19 + d LIBSSH2_ERROR_CHANNEL_OUTOFORDER... + d c -20 + d LIBSSH2_ERROR_CHANNEL_FAILURE... + d c -21 + d LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED... + d c -22 + d LIBSSH2_ERROR_CHANNEL_UNKNOWN... + d c -23 + d LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED... + d c -24 + d LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED... + d c -25 + d LIBSSH2_ERROR_CHANNEL_CLOSED... + d c -26 + d LIBSSH2_ERROR_CHANNEL_EOF_SENT... + d c -27 + d LIBSSH2_ERROR_SCP_PROTOCOL... + d c -28 + d LIBSSH2_ERROR_ZLIB... + d c -29 + d LIBSSH2_ERROR_SOCKET_TIMEOUT... + d c -30 + d LIBSSH2_ERROR_SFTP_PROTOCOL... + d c -31 + d LIBSSH2_ERROR_REQUEST_DENIED... + d c -32 + d LIBSSH2_ERROR_METHOD_NOT_SUPPORTED... + d c -33 + d LIBSSH2_ERROR_INVAL... + d c -34 + d LIBSSH2_ERROR_INVALID_POLL_TYPE... + d c -35 + d LIBSSH2_ERROR_PUBLICKEY_PROTOCOL... + d c -36 + d LIBSSH2_ERROR_EAGAIN... + d c -37 + d LIBSSH2_ERROR_BUFFER_TOO_SMALL... + d c -38 + d LIBSSH2_ERROR_BAD_USE... + d c -39 + d LIBSSH2_ERROR_COMPRESS... + d c -40 + d LIBSSH2_ERROR_OUT_OF_BOUNDARY... + d c -41 + d LIBSSH2_ERROR_AGENT_PROTOCOL... + d c -42 + d LIBSSH2_ERROR_SOCKET_RECV... + d c -43 + d LIBSSH2_ERROR_ENCRYPT... + d c -44 + d LIBSSH2_ERROR_BAD_SOCKET... + d c -45 + d LIBSSH2_ERROR_KNOWN_HOSTS... + d c -46 + + * this is a define to provide the old (<= 1.2.7) name. + d LIBSSH2_ERROR_BANNER_NONE... + d c -2 + + * Global API. + d LIBSSH2_INIT_NO_CRYPTO... + d c X'0001' + + * libssh2_init() + * + * Initialize the libssh2 functions. This typically initialize the + * crypto library. It uses a global state, and is not thread safe -- + * you must make sure this function is not called concurrently. + * + * Flags can be: + * 0: Normal initialize + * LIBSSH2_INIT_NO_CRYPTO: Do not initialize the crypto library + * (ie. OPENSSL_add_cipher_algorithms() for + * OpenSSL) + * + * Returns 0 if succeeded, or a negative value for error. + + d libssh2_init pr extproc('libssh2_init') + d like(libssh2_Cint) + d flags value like(libssh2_Cint) + + * libssh2_exit() + * + * Exit the libssh2 functions and free's all memory used internal. + + d libssh2_exit pr extproc('libssh2_exit') + + * libssh2_free() + * + * Deallocate memory allocated by earlier call to libssh2 functions. + + d libssh2_free pr extproc('libssh2_free') + d session * value LIBSSH2_SESSION * + d ptr * value void * + + * libssh2_session_supported_algs() + * + * Fills algs with a list of supported cryptographic algorithms. Returns a + * non-negative number (number of supported algorithms) on success or a + * negative number (an eror code) on failure. + * + * NOTE: on success, algs must be deallocated (by calling libssh2_free) + * when not needed anymore + + d libssh2_session_supported_algs... + d pr extproc( + d 'libssh2_session_supported_algs') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d method_type value like(libssh2_Cint) + d algs * const char **(*) + + * Session API. + d libssh2_session_init_ex... + d pr * extproc('libssh2_session_init_ex') LIBSSH2_SESSION * + d my_alloc * value procptr + d my_free * value procptr + d my_realloc * value procptr + d abstract * value void * + + * Implementation of C macro. + d libssh2_session_init... + d pr * extproc('libssh2_session_init') LIBSSH2_SESSION * + + d libssh2_session_abstract... + d pr * extproc('libssh2_session_abstract') void * * + d session * value LIBSSH2_SESSION * + + d libssh2_session_callback_set... + d pr * extproc( void * + d 'libssh2_session_callback_set') + d session * value LIBSSH2_SESSION * + d cbtype value like(libssh2_Cint) + d callback * value void * + + d libssh2_session_banner_set... + d pr extproc('libssh2_session_banner_set') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d banner * value options(*string) const char * + + d libssh2_banner_set... + d pr extproc('libssh2_banner_set') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d banner * value options(*string) const char * + + d libssh2_session_startup... + d pr extproc('libssh2_session_startup') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d sock value like(libssh2_Cint) + + d libssh2_session_handshake... + d pr extproc('libssh2_session_handshake') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d sock value like(libssh2_socket_t) + + d libssh2_session_disconnect_ex... + d pr extproc( + d 'libssh2_session_disconnect_ex') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d reason value like(libssh2_Cint) + d description * value options(*string) const char * + d lang * value options(*string) const char * + + * Implementation of C macro. + d libssh2_session_disconnect... + d pr extproc('libssh2_session_disconnect') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d description * value options(*string) const char * + + d libssh2_session_free... + d pr extproc('libssh2_session_free') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + + d libssh2_hostkey_hash... + d pr * extproc('libssh2_hostkey_hash') const char * + d session * value LIBSSH2_SESSION * + d hash_type value like(libssh2_Cint) + + d libssh2_session_hostkey... + d pr * extproc('libssh2_session_hostkey') const char * + d session * value LIBSSH2_SESSION * + d len like(libssh2_Csize_t) + d type like(libssh2_Cint) + + d libssh2_session_method_pref... + d pr extproc( + d 'libssh2_session_method_pref') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d method_type value like(libssh2_Cint) + d prefs * value options(*string) const char * + + d libssh2_session_methods... + d pr * extproc('libssh2_session_methods') const char * + d session * value LIBSSH2_SESSION * + d method_type value like(libssh2_Cint) + + d libssh2_session_last_error... + d pr extproc('libssh2_session_last_error') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d errmsg * char *(*) + d errmsg_len like(libssh2_Cint) + d want_buf value like(libssh2_Cint) + + d libssh2_session_last_errno... + d pr extproc('libssh2_session_last_errno') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + + d libssh2_session_set_last_error... + d pr extproc( + d 'libssh2_session_set_last_error') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d errcode value like(libssh2_Cint) + d errmsg * value options(*string) const char * + + d libssh2_session_block_directions... + d pr extproc( + d 'libssh2_session_block_directions') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + + d libssh2_session_flag... + d pr extproc('libssh2_session_flag') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d flag value like(libssh2_Cint) + d value value like(libssh2_Cint) + + d libssh2_session_banner_get... + d pr * extproc('libssh2_session_banner_get') const char * + d session * value LIBSSH2_SESSION * + + * Userauth API. + + d libssh2_userauth_list... + d pr * extproc('libssh2_userauth_list') char * + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d username_len value like(libssh2_Cuint) + + d libssh2_userauth_authenticated... + d pr extproc( + d 'libssh2_userauth_authenticated') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + + d libssh2_userauth_password_ex... + d pr extproc( + d 'libssh2_userauth_password_ex') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d username_len value like(libssh2_Cuint) + d password * value options(*string) const char * + d password_len value like(libssh2_Cuint) + d passwd_change_cb... + d * value procptr + + * Implementation of C macro. + d libssh2_userauth_password... + d pr extproc('libssh2_userauth_password') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d password * value options(*string) const char * + + d libssh2_userauth_publickey_fromfile_ex... + d pr extproc('libssh2_userauth_publickey_- + d fromfile_ex') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d username_len value like(libssh2_Cuint) + d publickey * value options(*string) const char * + d privatekey * value options(*string) const char * + d passphrase * value options(*string) const char * + + * Implementation of C macro. + d libssh2_userauth_publickey_fromfile... + d pr extproc( + d 'libssh2_userauth_publickey_fromfile' + d ) + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d publickey * value options(*string) const char * + d privatekey * value options(*string) const char * + d passphrase * value options(*string) const char * + + d libssh2_userauth_publickey... + d pr extproc('libssh2_userauth_publickey') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d pubkeydata * value options(*string) const unsigned char* + d pubkeydata_len... + d value like(libssh2_Csize_t) + d sign_callback * value procptr + d abstract * void *(*) + + d libssh2_userauth_hostbased_fromfile_ex... + d pr extproc('libssh2_userauth_hostbased_- + d fromfile_ex') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d username_len value like(libssh2_Cuint) + d publickey * value options(*string) const char * + d privatekey * value options(*string) const char * + d passphrase * value options(*string) const char * + d hostname * value options(*string) const char * + d hostname_len value like(libssh2_Cuint) + d local_username... + d * value options(*string) const char * + d local_username_len... + d value like(libssh2_Cuint) + + * C macro implementation. + d libssh2_userauth_hostbased_fromfile... + d pr extproc( + d 'libssh2_userauth_hostbased_fromfile' + d ) + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d publickey * value options(*string) const char * + d privatekey * value options(*string) const char * + d passphrase * value options(*string) const char * + d hostname * value options(*string) const char * + + d libssh2_userauth_publickey_frommemory... + d pr extproc('libssh2_userauth_publickey_- + d frommemory') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d username_len value like(libssh2_Csize_t) + d publickeyfiledata... + d * value options(*string) const char * + d publickeyfiledata_len... + d value like(libssh2_Csize_t) + d privatekeyfiledata... + d * value options(*string) const char * + d privatekeyfiledata_len... + d value like(libssh2_Csize_t) + d passphrase * value options(*string) const char * + + * response_callback is provided with filled by library prompts array, + * but client must allocate and fill individual responses. Responses + * array is already allocated. Responses data will be freed by libssh2 + * after callback return, but before subsequent callback invokation. + + d libssh2_userauth_keyboard_interactive_ex... + d pr extproc('libssh2_userauth_keyboard_i- + d nteractive_ex') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d username_len value like(libssh2_Cuint) + d response_callback... + d * value procptr + + * C macro implementation. + d libssh2_userauth_keyboard_interactive... + d pr extproc('libssh2_userauth_keyboard_i- + d nteractive') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d username * value options(*string) const char * + d response_callback... + d * value procptr + + d libssh2_poll pr extproc('libssh2_poll') + d like(libssh2_Cint) + d fds * value LIBSSH2_POLLFD * + d nfds value like(libssh2_Cuint) + d timeout value like(libssh2_Clong) + + * Channel API. + d LIBSSH2_CHANNEL_WINDOW_DEFAULT... + d c X'00200000' + d LIBSSH2_CHANNEL_PACKET_DEFAULT... + d c 32768 + d LIBSSH2_CHANNEL_MINADJUST... + d c 1024 + + * Extended Data Handling. + d LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL... + d c 0 + d LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE... + d c 1 + d LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE... + d c 2 + + d SSH_EXTENDED_DATA_STDERR... + d c 1 + + * Returned by any function that would block during a read/write + * operation. + d LIBSSH2CHANNEL_EAGAIN... LIBSSH2_ERROR_EAGAIN + d c -37 + + d libssh2_channel_open_ex... + d pr * extproc('libssh2_channel_open_ex') LIBSSH2_CHANNEL * + d session * value LIBSSH2_SESSION * + d channel_type * value options(*string) const char * + d channel_type_len... + d value like(libssh2_Cuint) + d window_size value like(libssh2_Cuint) + d packet_size value like(libssh2_Cuint) + d message * value options(*string) const char * + d message_len value like(libssh2_Cuint) + + * C macro implementation. + d libssh2_channel_open_session... + d pr * extproc( LIBSSH2_CHANNEL * + d 'libssh2_channel_open_session') + d session * value LIBSSH2_SESSION * + + d libssh2_channel_direct_tcpip_ex... + d pr * extproc( LIBSSH2_CHANNEL * + d 'libssh2_channel_direct_tcpip_ex') + d session * value LIBSSH2_SESSION * + d host * value options(*string) const char * + d port value like(libssh2_Cint) + d shost * value options(*string) const char * + d sport value like(libssh2_Cint) + + * C macro implementation. + d libssh2_channel_direct_tcpip... + d pr * extproc( LIBSSH2_CHANNEL * + d 'libssh2_channel_direct_tcpip') + d session * value LIBSSH2_SESSION * + d host * value options(*string) const char * + d port value like(libssh2_Cint) + + d libssh2_channel_forward_listen_ex... + d pr * extproc( LIBSSH2_LISTENER * + d 'libssh2_channel_forward_listen_ex') + d session * value LIBSSH2_SESSION * + d host * value options(*string) const char * + d port value like(libssh2_Cint) + d bound_port like(libssh2_Cint) + d queue_maxsize value like(libssh2_Cint) + + * C macro implementation. + d libssh2_channel_forward_listen... + d pr * extproc( LIBSSH2_LISTENER * + d 'libssh2_channel_forward_listen') + d session * value LIBSSH2_SESSION * + d port value like(libssh2_Cint) + + d libssh2_channel_forward_cancel... + d pr extproc( + d 'libssh2_channel_forward_cancel') + d like(libssh2_Cint) + d listener * value LIBSSH2_LISTENER * + + d libssh2_channel_forward_accept... + d pr * extproc( LIBSSH2_CHANNEL * + d 'libssh2_channel_forward_accept') + d listener * value LIBSSH2_LISTENER * + + d libssh2_channel_setenv_ex... + d pr extproc('libssh2_channel_setenv_ex') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d varname * value options(*string) const char * + d varname_len value like(libssh2_Cuint) + d value * value options(*string) const char * + d value_len value like(libssh2_Cuint) + + * C macro implementation. + d libssh2_channel_setenv... + d pr extproc('libssh2_channel_setenv') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d varname * value options(*string) const char * + d value * value options(*string) const char * + + d libssh2_channel_request_pty_ex... + d pr extproc( + d 'libssh2_channel_request_pty_ex') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d term * value options(*string) const char * + d term_len value like(libssh2_Cuint) + d modes * value options(*string) const char * + d modes_len value like(libssh2_Cuint) + d width value like(libssh2_Cint) + d height value like(libssh2_Cint) + d width_px value like(libssh2_Cint) + d height_px value like(libssh2_Cint) + + * C macro implementation. + d libssh2_channel_request_pty... + d pr extproc( + d 'libssh2_channel_request_pty') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d term * value options(*string) const char * + + d libssh2_channel_request_pty_size_ex... + d pr extproc( + d 'libssh2_channel_request_pty_size_ex' + d ) + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d width value like(libssh2_Cint) + d height value like(libssh2_Cint) + d width_px value like(libssh2_Cint) + d height_px value like(libssh2_Cint) + + * C macro implementation. + d libssh2_channel_request_pty_size... + d pr extproc( + d 'libssh2_channel_request_pty_size') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d width value like(libssh2_Cint) + d height value like(libssh2_Cint) + + d libssh2_channel_x11_req_ex... + d pr extproc('libssh2_channel_x11_req_ex') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d single_connection... + d value like(libssh2_Cint) + d auth_proto * value options(*string) const char * + d auth_cookie * value options(*string) const char * + d screen_number value like(libssh2_Cint) + + * C macro implementation. + d libssh2_channel_x11_req... + d pr extproc('libssh2_channel_x11_req') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d screen_number value like(libssh2_Cint) + + d libssh2_channel_process_startup... + d pr extproc( + d 'libssh2_channel_process_startup') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d request * value options(*string) const char * + d request_len value like(libssh2_Cuint) + d message * value options(*string) const char * + d message_len value like(libssh2_Cuint) + + * C macro implementation. + d libssh2_channel_shell... + d pr extproc('libssh2_channel_shell') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + * C macro implementation. + d libssh2_channel_exec... + d pr extproc('libssh2_channel_exec') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d command * value options(*string) const char * + + * C macro implementation. + d libssh2_channel_subsystem... + d pr extproc('libssh2_channel_subsystem') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d subsystem * value options(*string) const char * + + d libssh2_channel_read_ex... + d pr extproc('libssh2_channel_read_ex') + d like(libssh2_Cssize_t) + d channel * value LIBSSH2_CHANNEL * + d stream_id value like(libssh2_Cint) + d buf * value char * + d buflen value like(libssh2_Csize_t) + + * C macro implementation. + d libssh2_channel_read... + d pr extproc('libssh2_channel_read') + d like(libssh2_Cssize_t) + d channel * value LIBSSH2_CHANNEL * + d buf * value char * + d buflen value like(libssh2_Csize_t) + + * C macro implementation. + d libssh2_channel_read_stderr... + d pr extproc( + d 'libssh2_channel_read_stderr') + d like(libssh2_Cssize_t) + d channel * value LIBSSH2_CHANNEL * + d buf * value char * + d buflen value like(libssh2_Csize_t) + + d libssh2_poll_channel_read... + d pr extproc('libssh2_poll_channel_read') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d extended value like(libssh2_Cint) + + d libssh2_channel_window_read_ex... + d pr extproc( + d 'libssh2_channel_window_read_ex') + d like(libssh2_Culong) + d channel * value LIBSSH2_CHANNEL * + d read_avail like(libssh2_Culong) + d window_size_initial... + d like(libssh2_Culong) + + * C macro implementation. + d libssh2_channel_window_read... + d pr extproc( + d 'libssh2_channel_window_read') + d like(libssh2_Culong) + d channel * value LIBSSH2_CHANNEL * + + d libssh2_channel_receive_window_adjust2... + d pr extproc('libssh2_channel_receive_win- + d dow_adjust2') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d adjustment value like(libssh2_Culong) + d force value like(libssh2_Cuchar) + d storewindow like(libssh2_Cuint) + + d libssh2_channel_write_ex... + d pr extproc('libssh2_channel_write_ex') + d like(libssh2_Cssize_t) + d channel * value LIBSSH2_CHANNEL * + d stream_id value like(libssh2_Cint) + d buf * value options(*string) const char * + d buflen value like(libssh2_Csize_t) + + * C macro implementation. + d libssh2_channel_write... + d pr extproc('libssh2_channel_write') + d like(libssh2_Cssize_t) + d channel * value LIBSSH2_CHANNEL * + d buf * value options(*string) const char * + d buflen value like(libssh2_Csize_t) + + * C macro implementation. + d libssh2_channel_write_stderr... + d pr extproc( + d 'libssh2_channel_write_stderr') + d like(libssh2_Cssize_t) + d channel * value LIBSSH2_CHANNEL * + d buf * value options(*string) const char * + d buflen value like(libssh2_Csize_t) + + d libssh2_channel_window_write_ex... + d pr extproc( + d 'libssh2_channel_window_write_ex') + d like(libssh2_Culong) + d channel * value LIBSSH2_CHANNEL * + d window_size_initial... + d like(libssh2_Culong) + + * C macro implementation. + d libssh2_channel_window_write... + d pr extproc( + d 'libssh2_channel_window_write') + d like(libssh2_Culong) + d channel * value LIBSSH2_CHANNEL * + + d libssh2_session_set_blocking... + d pr extproc( + d 'libssh2_session_set_blocking') + d session * value LIBSSH2_SESSION * + d blocking value like(libssh2_Cint) + + d libssh2_session_get_blocking... + d pr extproc( + d 'libssh2_session_get_blocking') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + + d libssh2_channel_set_blocking... + d pr extproc( + d 'libssh2_channel_set_blocking') + d channel * value LIBSSH2_CHANNEL * + d blocking value like(libssh2_Cint) + + d libssh2_session_set_timeout... + d pr extproc( + d 'libssh2_session_set_timeout') + d session * value LIBSSH2_SESSION * + d timeout value like(libssh2_Clong) + + d libssh2_session_get_timeout... + d pr extproc( + d 'libssh2_session_get_timeout') + d like(libssh2_Clong) + d session * value LIBSSH2_SESSION * + + d libssh2_channel_handle_extended_data2... + d pr extproc('libssh2_channel_handle_exte- + d nded_data2') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d ignore_mode value like(libssh2_Cint) + + * libssh2_channel_ignore_extended_data() is defined below for BC with + * version 0.1. + + d LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA... + d c -1 + d LIBSSH2_CHANNEL_FLUSH_ALL... + d c -2 + + d libssh2_channel_flush_ex... + d pr extproc('libssh2_channel_flush_ex') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d streamid value like(libssh2_Cint) + + * C macro implementation. + d libssh2_channel_flush... + d pr extproc('libssh2_channel_flush') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + * C macro implementation. + d libssh2_channel_flush_stderr... + d pr extproc( + d 'libssh2_channel_flush_stderr') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + d libssh2_channel_get_exit_status... + d pr extproc( + d 'libssh2_channel_get_exit_status') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + d libssh2_channel_get_exit_signal... + d pr extproc( + d 'libssh2_channel_get_exit_signal') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + d exitsignal * char *(*) + d exitsignal_len... + d like(libssh2_Csize_t) + d errmsg * char *(*) + d errmsg_len like(libssh2_Csize_t) + d langtag * char *(*) + d langtag_len like(libssh2_Csize_t) + + d libssh2_channel_send_eof... + d pr extproc('libssh2_channel_send_eof') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + d libssh2_channel_eof... + d pr extproc('libssh2_channel_eof') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + d libssh2_channel_wait_eof... + d pr extproc('libssh2_channel_wait_eof') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + d libssh2_channel_close... + d pr extproc('libssh2_channel_close') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + d libssh2_channel_wait_closed... + d pr extproc( + d 'libssh2_channel_wait_closed') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + d libssh2_channel_free... + d pr extproc('libssh2_channel_free') + d like(libssh2_Cint) + d channel * value LIBSSH2_CHANNEL * + + * Use libssh2_scp_recv2 for large (> 2GB) file support. + d libssh2_scp_recv2... + d pr * extproc('libssh2_scp_recv2') LIBSSH2_CHANNEL * + d session * value LIBSSH2_SESSION * + d path * value options(*string) const char * + d sb likeds(libssh2_struct_stat) + + d libssh2_scp_send_ex... + d pr * extproc('libssh2_scp_send_ex') LIBSSH2_CHANNEL * + d session * value LIBSSH2_SESSION * + d path * value options(*string) const char * + d mode value like(libssh2_Cint) + d size value like(libssh2_Csize_t) + d mtime value like(libssh2_Clong) + d atime value like(libssh2_Clong) + + d libssh2_scp_send64... + d pr * extproc('libssh2_scp_send64') LIBSSH2_CHANNEL * + d session * value LIBSSH2_SESSION * + d path * value options(*string) const char * + d mode value like(libssh2_Cint) + d size value like(libssh2_int64_t) + d mtime value like(libssh2_time_t) + d atime value like(libssh2_time_t) + + * C macro implementation. + d libssh2_scp_send... + d pr * extproc('libssh2_scp_send') LIBSSH2_CHANNEL * + d session * value LIBSSH2_SESSION * + d path * value options(*string) const char * + d mode value like(libssh2_Cint) + d size value like(libssh2_int64_t) + + d libssh2_base64_decode... + d pr extproc('libssh2_base64_decode') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d dest * value char * * + d dest_len * value unsigned int * + d src * value options(*string) const char * + d src_len value like(libssh2_Cuint) + + * Procedure libssh2_version renamed to avoid upper/lower case name clash. + d libssh2_get_version... + d pr * extproc('libssh2_version') const char * + d req_version_num... + d value like(libssh2_Cint) + + d HAVE_LIBSSH2_KNOWNHOST_API... since 1.1.1 + d c X'010101' + d HAVE_LIBSSH2_VERSION_API... since 1.1 + d c X'010100' + + d libssh2_knownhost... + d ds based(######typedef######) + d align qualified + d magic like(libssh2_Cuint) + d node * void * + d name * char * + d key * char * + d typemask like(libssh2_Cint) + + * libssh2_knownhost_init + * + * Init a collection of known hosts. Returns the pointer to a collection. + + d libssh2_knownhost_init... + d pr * extproc('libssh2_knownhost_init') LIBSSH2_KNOWNHOSTS * + d session * value LIBSSH2_SESSION * + + * libssh2_knownhost_add + * + * Add a host and its associated key to the collection of known hosts. + * + * The 'type' argument specifies on what format the given host and + * keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. + * If a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() + * function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + + * host format (2 bits). + d LIBSSH2_KNOWNHOST_TYPE_MASK... + d c X'FFFF' + d LIBSSH2_KNOWNHOST_TYPE_PLAIN... + d c 1 + d LIBSSH2_KNOWNHOST_TYPE_SHA1... always base64 ncoded + d c 2 + d LIBSSH2_KNOWNHOST_TYPE_CUSTOM... + d c 3 + + * key format (2 bits). + d LIBSSH2_KNOWNHOST_KEYENC_MASK... + d c X'00030000' + d LIBSSH2_KNOWNHOST_KEYENC_RAW... + d c X'00010000' + d LIBSSH2_KNOWNHOST_KEYENC_BASE64... + d c X'00020000' + + * type of key (3 bits). + d LIBSSH2_KNOWNHOST_KEY_MASK... + d c X'001C0000' + d LIBSSH2_KNOWNHOST_KEY_SHIFT... + d c 18 + d LIBSSH2_KNOWNHOST_KEY_RSA1... + d c X'00040000' + d LIBSSH2_KNOWNHOST_KEY_SSHRSA... + d c X'00080000' + d LIBSSH2_KNOWNHOST_KEY_SSHDSS... + d c X'000C0000' + d LIBSSH2_KNOWNHOST_KEY_UNKNOWN... + d c X'001C0000' + + d libssh2_knownhost_add... + d pr extproc('libssh2_knownhost_add') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d host * value options(*string) const char * + d salt * value options(*string) const char * + d key * value options(*string) const char * + d keylen value like(libssh2_Csize_t) + d typemask value like(libssh2_Cint) + d store * libssh2_knownhost * + + * libssh2_knownhost_addc + * + * Add a host and its associated key to the collection of known hosts. + * + * Takes a comment argument that may be NULL. A NULL comment indicates + * there is no comment and the entry will end directly after the key + * when written out to a file. An empty string "" comment will indicate an + * empty comment which will cause a single space to be written after the + * key. + * + * The 'type' argument specifies on what format the given host and keys + * are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. + * If a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() + * function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + + d libssh2_knownhost_addc... + d pr extproc('libssh2_knownhost_addc') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d host * value options(*string) const char * + d salt * value options(*string) const char * + d key * value options(*string) const char * + d keylen value like(libssh2_Csize_t) + d comment * value options(*string) const char * + d commentlen value like(libssh2_Csize_t) + d typemask value like(libssh2_Cint) + d store * libssh2_knownhost * + + + * libssh2_knownhost_check + * + * Check a host and its associated key against the collection of known + * hosts. + * + * The type is the type/format of the given host name. + * + * plain - ascii "hostname.domain.tld" + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * + * 'knownhost' may be set to NULL if you don't care about that info. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_* values, see below. + + d LIBSSH2_KNOWNHOST_CHECK_MATCH... + d c 0 + d LIBSSH2_KNOWNHOST_CHECK_MISMATCH... + d c 1 + d LIBSSH2_KNOWNHOST_CHECK_NOTFOUND... + d c 2 + d LIBSSH2_KNOWNHOST_CHECK_FAILURE... + d c 3 + + d libssh2_knownhost_check... + d pr extproc('libssh2_knownhost_check') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d host * value options(*string) const char * + d key * value options(*string) const char * + d keylen value like(libssh2_Csize_t) + d typemask value like(libssh2_Cint) + d knownhost * libssh2_knownhost * + + * this function is identital to the above one, but also takes a port + * argument that allows libssh2 to do a better check. + d libssh2_knownhost_checkp... + d pr extproc('libssh2_knownhost_checkp') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d host * value options(*string) const char * + d port value like(libssh2_Cint) + d key * value options(*string) const char * + d keylen value like(libssh2_Csize_t) + d typemask value like(libssh2_Cint) + d knownhost * libssh2_knownhost * + + * libssh2_knownhost_del + * + * Remove a host from the collection of known hosts. The 'entry' struct is + * retrieved by a call to libssh2_knownhost_check(). + + d libssh2_knownhost_del... + d pr extproc('libssh2_knownhost_del') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d entry likeds(libssh2_knownhost) + + * libssh2_knownhost_free + * + * Free an entire collection of known hosts. + + d libssh2_knownhost_free... + d pr extproc('libssh2_knownhost_free') + d hosts * value LIBSSH2_KNOWNHOSTS * + + * libssh2_knownhost_readline() + * + * Pass in a line of a file of 'type'. It makes libssh2 read this line. + * + * LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type. + + d libssh2_knownhost_readline... + d pr extproc('libssh2_knownhost_readline') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d line * value options(*string) const char * + d len value like(libssh2_Csize_t) + d type value like(libssh2_Cint) + + * libssh2_knownhost_readfile + * + * Add hosts+key pairs from a given file. + * + * Returns a negative value for error or number of successfully added + * hosts. + * + * This implementation currently only knows one 'type' (openssh), all + * others are reserved for future use. + + d LIBSSH2_KNOWNHOST_FILE_OPENSSH... + d c 1 + + d libssh2_knownhost_readfile... + d pr extproc('libssh2_knownhost_readfile') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d filename * value options(*string) const char * + d type value like(libssh2_Cint) + + * libssh2_knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the + * given output buffer is too small to hold the desired output. + * + * This implementation currently only knows one 'type' (openssh), all + * others are reserved for future use. + + d libssh2_knownhost_writeline... + d pr extproc( + d 'libssh2_knownhost_writeline') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d known likeds(libssh2_knownhost) + d buffer * value options(*string) char * + d buflen value like(libssh2_Csize_t) + d outlen like(libssh2_Csize_t) Written data amount + d type value like(libssh2_Cint) + + * libssh2_knownhost_writefile + * + * Write hosts+key pairs to a given file. + * + * This implementation currently only knows one 'type' (openssh), all + * others are reserved for future use. + + d libssh2_knownhost_writefile... + d pr extproc( + d 'libssh2_knownhost_writefile') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d filename * value options(*string) const char * + d type value like(libssh2_Cint) + + * libssh2_knownhost_get() + * + * Traverse the internal list of known hosts. Pass NULL to 'prev' to get + * the first one. Or pass a poiner to the previously returned one to + * get the next. + * + * Returns: + * 0 if a fine host was stored in 'store' + * 1 if end of hosts + * [negative] on errors + + d libssh2_knownhost_get... + d pr extproc('libssh2_knownhost_get') + d like(libssh2_Cint) + d hosts * value LIBSSH2_KNOWNHOSTS * + d store * libssh2_knownhost * + d prev likeds(libssh2_knownhost) + + d HAVE_LIBSSH2_AGENT_API... since 1.2.2 + d c X'010202' + + d libssh2_agent_publickey... + d ds based(######typedef######) + d align qualified + d magic like(libssh2_Cuint) + d node * void * + d blob * unsigned char * + d blob_len like(libssh2_Csize_t) + d comment * char * + + * libssh2_agent_init + * + * Init an ssh-agent handle. Returns the pointer to the handle. + + d libssh2_agent_init... + d pr * extproc('libssh2_agent_init') LIBSSH2_AGENT * + d session * value LIBSSH2_SESSION * + + * libssh2_agent_connect() + * + * Connect to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + + d libssh2_agent_connect... + d pr extproc('libssh2_agent_connect') + d like(libssh2_Cint) + d agent * value LIBSSH2_AGENT * + + * libssh2_agent_list_identities() + * + * Request an ssh-agent to list identities. + * + * Returns 0 if succeeded, or a negative value for error. + + d libssh2_agent_list_identities... + d pr extproc( + d 'libssh2_agent_list_identities') + d like(libssh2_Cint) + d agent * value LIBSSH2_AGENT * + + * libssh2_agent_get_identity() + * + * Traverse the internal list of public keys. Pass NULL to 'prev' to get + * the first one. Or pass a poiner to the previously returned one to + * get the next. + * + * Returns: + * 0 if a fine public key was stored in 'store' + * 1 if end of public keys + * [negative] on errors + + d libssh2_agent_get_identity... + d pr extproc('libssh2_agent_get_identity') + d like(libssh2_Cint) + d agent * value LIBSSH2_AGENT * + d store * libssh2_agent_... + d publickey *(*) + d prev likeds(libssh2_agent_publickey) + + * libssh2_agent_userauth() + * + * Do publickey user authentication with the help of ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + + d libssh2_agent_userauth... + d pr extproc('libssh2_agent_userauth') + d like(libssh2_Cint) + d agent * value LIBSSH2_AGENT * + d username * value options(*string) const char * + d identity likeds(libssh2_agent_publickey) + + * libssh2_agent_disconnect() + * + * Close a connection to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + + d libssh2_agent_disconnect... + d pr extproc('libssh2_agent_disconnect') + d like(libssh2_Cint) + d agent * value LIBSSH2_AGENT * + + * libssh2_agent_free() + * + * Free an ssh-agent handle. This function also frees the internal + * collection of public keys. + + d libssh2_agent_free... + d pr extproc('libssh2_agent_free') + d agent * value LIBSSH2_AGENT * + + + * libssh2_keepalive_config() + * + * Set how often keepalive messages should be sent. WANT_REPLY + * indicates whether the keepalive messages should request a response + * from the server. INTERVAL is number of seconds that can pass + * without any I/O, use 0 (the default) to disable keepalives. To + * avoid some busy-loop corner-cases, if you specify an interval of 1 + * it will be treated as 2. + * + * Note that non-blocking applications are responsible for sending the + * keepalive messages using libssh2_keepalive_send(). + + d libssh2_keepalive_config... + d pr extproc('libssh2_keepalive_config') + d session * value LIBSSH2_SESSION * + d want_reply value like(libssh2_Cint) + d interval value like(libssh2_Cuint) + + * libssh2_keepalive_send() + * + * Send a keepalive message if needed. SECONDS_TO_NEXT indicates how + * many seconds you can sleep after this call before you need to call + * it again. Returns 0 on success, or LIBSSH2_ERROR_SOCKET_SEND on + * I/O errors. + + d libssh2_keepalive_send... + d pr extproc('libssh2_keepalive_send') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d seconds_to_next... + d like(libssh2_Cint) + + * NOTE NOTE NOTE + * libssh2_trace() has no function in builds that aren't built with debug + * enabled. + + d libssh2_trace pr extproc('libssh2_trace') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d bitmask value like(libssh2_Cint) + + d LIBSSH2_TRACE_TRANS... + d c X'0002' + d LIBSSH2_TRACE_KEX... + d c X'0004' + d LIBSSH2_TRACE_AUTH... + d c X'0008' + d LIBSSH2_TRACE_CONN... + d c X'0010' + d LIBSSH2_TRACE_SCP... + d c X'0020' + d LIBSSH2_TRACE_SFTP... + d c X'0040' + d LIBSSH2_TRACE_ERROR... + d c X'0080' + d LIBSSH2_TRACE_PUBLICKEY... + d c X'0100' + d LIBSSH2_TRACE_SOCKET... + d c X'0200' + + d libssh2_trace_handler_func... + d s * based(######typedef######) procptr + + d libssh2_trace_sethandler... + d pr extproc('libssh2_trace_sethandler') + d like(libssh2_Cint) + d session * value LIBSSH2_SESSION * + d context * value void * + d callback value + d like(libssh2_trace_handler_func) + + /endif LIBSSH2_H_ diff --git a/libssh2/os400/libssh2rpg/libssh2_ccsid.rpgle.in b/libssh2/os400/libssh2rpg/libssh2_ccsid.rpgle.in new file mode 100644 index 000000000..345fa6303 --- /dev/null +++ b/libssh2/os400/libssh2rpg/libssh2_ccsid.rpgle.in @@ -0,0 +1,69 @@ + * Copyright (c) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + + /if not defined(LIBSSH2_CCSID_H_) + /define LIBSSH2_CCSID_H_ + + /include "libssh2rpg/libssh2" + + d libssh2_from_ccsid... + d pr * extproc('libssh2_from_ccsid') char * + d session * value LIBSSH2_SESSION * + d cache * libssh2_string_cache + d *(*) + d ccsid value like(libssh2_Cushort) + d string * value options(*string) const char * + d inlen value like(libssh2_Cssize_t) + d outlen like(libssh2_Csize_t) options(*omit) + + d libssh2_to_ccsid... + d pr * extproc('libssh2_to_ccsid') char * + d session * value LIBSSH2_SESSION * + d cache * libssh2_string_cache + d *(*) + d ccsid value like(libssh2_Cushort) + d string * value options(*string) const char * + d inlen value like(libssh2_Cssize_t) + d outlen like(libssh2_Csize_t) options(*omit) + + d libssh2_release_string_cache... + d pr extproc( + d 'libssh2_release_string_cache') + d session * value LIBSSH2_SESSION * + d cache * libssh2_string_cache + d *(*) + + /endif LIBSSH2_CCSID_H_ diff --git a/libssh2/os400/libssh2rpg/libssh2_publickey.rpgle b/libssh2/os400/libssh2rpg/libssh2_publickey.rpgle new file mode 100644 index 000000000..4387b0d3a --- /dev/null +++ b/libssh2/os400/libssh2rpg/libssh2_publickey.rpgle @@ -0,0 +1,141 @@ + * Copyright (c) 2015, Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + + * Note: This include file is only needed for using the + * publickey SUBSYSTEM which is not the same as publickey + * authentication. For authentication you only need libssh2.h + * + * For more information on the publickey subsystem, + * refer to IETF draft: secsh-publickey + + /if not defined(LIBSSH2_PUBLICKEY_H_) + /define LIBSSH2_PUBLICKEY_H_ + + /include "libssh2rpg/libssh2" + + d libssh2_publickey_attribute... + d ds based(######typedef######) + d align qualified + d name * const char * + d name_len like(libssh2_Culong) + d value * const char * + d value_len like(libssh2_Culong) + d mandatory like(libssh2_Cchar) + + d libssh2_publickey_list... + d ds based(######typedef######) + d align qualified + d name * const char * + d name_len like(libssh2_Culong) + d blob * const uns char * + d blob_len like(libssh2_Culong) + d num_attrs like(libssh2_Culong) + d attrs * libssh2_publickey... + d attribute * + + * Publickey Subsystem. + d libssh2_publickey_init... + d pr * extproc('libssh2_publickey_init') LIBSSH2_PUBLICKEY * + d session * value LIBSSH2_SESSION * + + d libssh2_publickey_add_ex... + d pr extproc('libssh2_publickey_add_ex') + d like(libssh2_Cint) + d pkey * value LIBSSH2_PUBLICKEY * + d name * value options(*string) const uns char * + d name_len value like(libssh2_Culong) + d blob * value options(*string) const uns char * + d blob_len value like(libssh2_Culong) + d overwrite value like(libssh2_Cchar) + d num_attrs value like(libssh2_Culong) + d attrs likeds(libssh2_publickey_attribute) + d dim(1000) + + * C macro implementation. + d libssh2_publickey_add... + d pr extproc('libssh2_publickey_add') + d like(libssh2_Cint) + d pkey * value LIBSSH2_PUBLICKEY * + d name * value options(*string) const unsigned char + d * + d blob * value options(*string) const unsigned char + d * + d blob_len value like(libssh2_Culong) + d overwrite value like(libssh2_Cchar) + d num_attrs value like(libssh2_Culong) + d attrs likeds(libssh2_publickey_attribute) + d dim(1000) + + d libssh2_publickey_remove_ex... + d pr extproc( + d 'libssh2_publickey_remove_ex') + d like(libssh2_Cint) + d pkey * value LIBSSH2_PUBLICKEY * + d name * value options(*string) const uns char * + d name_len value like(libssh2_Culong) + d blob * value options(*string) const uns char * + d blob_len value like(libssh2_Culong) + + * C macro implementation. + d libssh2_publickey_remove... + d pr extproc('libssh2_publickey_remove') + d like(libssh2_Cint) + d pkey * value LIBSSH2_PUBLICKEY * + d name * value options(*string) const uns char * + d blob * value options(*string) const uns char * + d blob_len value like(libssh2_Culong) + + d libssh2_publickey_list_fetch... + d pr extproc( + d 'libssh2_publickey_list_fetch') + d like(libssh2_Cint) + d pkey * value LIBSSH2_PUBLICKEY * + d num_keys * value unsigned long * + d pkey_list * libssh2_publickey... + d _list *(*) + + d libssh2_publickey_list_free... + d pr extproc( + d 'libssh2_publickey_list_free') + d pkey * value LIBSSH2_PUBLICKEY * + d pkey_list likeds(libssh2_publickey_list) + + d libssh2_publickey_shutdown... + d pr extproc('libssh2_publickey_shutdown') + d like(libssh2_Cint) + d pkey * value LIBSSH2_PUBLICKEY * + + /endif LIBSSH2_PUBLICKEY_H_ diff --git a/libssh2/os400/libssh2rpg/libssh2_sftp.rpgle b/libssh2/os400/libssh2rpg/libssh2_sftp.rpgle new file mode 100644 index 000000000..f4068fc8f --- /dev/null +++ b/libssh2/os400/libssh2rpg/libssh2_sftp.rpgle @@ -0,0 +1,621 @@ + * Copyright (c) 2015, Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + + /if not defined(LIBSSH2_SFTP_H_) + /define LIBSSH2_SFTP_H_ + + /include "libssh2rpg/libssh2" + + * Note: Version 6 was documented at the time of writing + * However it was marked as "DO NOT IMPLEMENT" due to pending changes + * + * Let's start with Version 3 (The version found in OpenSSH) and go from + * there. + d LIBSSH2_SFTP_VERSION... + d c 3 + + * Flags for open_ex(). + d LIBSSH2_SFTP_OPENFILE... + d c 0 + d LIBSSH2_SFTP_OPENDIR... + d c 1 + + * Flags for rename_ex(). + d LIBSSH2_SFTP_RENAME_OVERWRITE... + d c X'00000001' + d LIBSSH2_SFTP_RENAME_ATOMIC... + d c X'00000002' + d LIBSSH2_SFTP_RENAME_NATIVE... + d c X'00000004' + + * Flags for stat_ex(). + d LIBSSH2_SFTP_STAT... + d c 0 + d LIBSSH2_SFTP_LSTAT... + d c 1 + d LIBSSH2_SFTP_SETSTAT... + d c 2 + + * Flags for symlink_ex(). + d LIBSSH2_SFTP_SYMLINK... + d c 0 + d LIBSSH2_SFTP_READLINK... + d c 1 + d LIBSSH2_SFTP_REALPATH... + d c 2 + + * SFTP attribute flag bits. + d LIBSSH2_SFTP_ATTR_SIZE... + d c X'00000001' + d LIBSSH2_SFTP_ATTR_UIDGID... + d c X'00000002' + d LIBSSH2_SFTP_ATTR_PERMISSIONS... + d c X'00000004' + d LIBSSH2_SFTP_ATTR_ACMODTIME... + d c X'00000008' + d LIBSSH2_SFTP_ATTR_EXTENDED... + d c X'80000000' + + * SFTP statvfs flag bits. + d LIBSSH2_SFTP_ST_RDONLY... + d c X'00000001' + d LIBSSH2_SFTP_ST_NOSUID... + d c X'00000002' + + d #LIBSSH2_SFTP_ATTRIBUTES... + d ds based(######typedef######) + d align qualified + * If flags & ATTR_* bit is set, then the value in this struct will be + * meaningful Otherwise it should be ignored. + d flags like(libssh2_Culong) + d filesize like(libssh2_uint64_t) + d uid like(libssh2_Culong) + d gid like(libssh2_Culong) + d permissions like(libssh2_Culong) + d atime like(libssh2_Culong) + d mtime like(libssh2_Culong) + + d #LIBSSH2_SFTP_STATVFS... + d ds based(######typedef######) + d align qualified + d f_bsize like(libssh2_uint64_t) Filesys block size + d f_frsize like(libssh2_uint64_t) Fragment size + d f_blocks like(libssh2_uint64_t) FS size in f_frsize + d f_bfree like(libssh2_uint64_t) Free blocks + d f_bavail like(libssh2_uint64_t) Free blks f. nonroot + d f_files like(libssh2_uint64_t) Inodes + d f_ffree like(libssh2_uint64_t) Free inodes + d f_favail like(libssh2_uint64_t) Free inds f. nonroot + d f_fsid like(libssh2_uint64_t) File system ID + d f_flag like(libssh2_uint64_t) Mount flags + d f_namemax like(libssh2_uint64_t) Max filename length + + * SFTP filetypes. + d LIBSSH2_SFTP_TYPE_REGULAR... + d c 1 + d LIBSSH2_SFTP_TYPE_DIRECTORY... + d c 2 + d LIBSSH2_SFTP_TYPE_SYMLINK... + d c 3 + d LIBSSH2_SFTP_TYPE_SPECIAL... + d c 4 + d LIBSSH2_SFTP_TYPE_UNKNOWN... + d c 5 + d LIBSSH2_SFTP_TYPE_SOCKET... + d c 6 + d LIBSSH2_SFTP_TYPE_CHAR_DEVICE... + d c 7 + d LIBSSH2_SFTP_TYPE_BLOCK_DEVICE... + d c 8 + d LIBSSH2_SFTP_TYPE_FIFO... + d c 9 + + * Reproduce the POSIX file modes here for systems that are not POSIX + * compliant. + * + * These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES" + + * File type. + d LIBSSH2_SFTP_S_IFMT... type of file mask + d c X'F000' + d LIBSSH2_SFTP_S_IFIFO... named pipe (fifo) + d c X'1000' + d LIBSSH2_SFTP_S_IFCHR... character special + d c X'2000' + d LIBSSH2_SFTP_S_IFDIR... directory + d c X'4000' + d LIBSSH2_SFTP_S_IFBLK... block special + d c X'6000' + d LIBSSH2_SFTP_S_IFREG... regular + d c X'8000' + d LIBSSH2_SFTP_S_IFLNK... symbolic link + d c X'A000' + d LIBSSH2_SFTP_S_IFSOCK... socket + d c X'C000' + + * File mode. + * Read, write, execute/search by owner. + d LIBSSH2_SFTP_S_IRWXU... RWX mask for owner + d c X'01C0' + d LIBSSH2_SFTP_S_IRUSR... R for owner + d c X'0100' + d LIBSSH2_SFTP_S_IWUSR... W for owner + d c X'0080' + d LIBSSH2_SFTP_S_IXUSR... X for owner + d c X'0040' + * Read, write, execute/search by group. + d LIBSSH2_SFTP_S_IRWXG... RWX mask for group + d c X'0038' + d LIBSSH2_SFTP_S_IRGRP... R for group + d c X'0020' + d LIBSSH2_SFTP_S_IWGRP... W for group + d c X'0010' + d LIBSSH2_SFTP_S_IXGRP... X for group + d c X'0008' + * Read, write, execute/search by others. + d LIBSSH2_SFTP_S_IRWXO... RWX mask for other + d c X'0007' + d LIBSSH2_SFTP_S_IROTH... R for other + d c X'0004' + d LIBSSH2_SFTP_S_IWOTH... W for other + d c X'0002' + d LIBSSH2_SFTP_S_IXOTH... X for other + d c X'0001' + + * C macro implementation. + d LIBSSH2_SFTP_S_ISLNK... + d pr extproc('LIBSSH2_SFTP_S_ISLNK') + d like(libssh2_Cint) + d permissions value like(libssh2_Culong) + + * C macro implementation. + d LIBSSH2_SFTP_S_ISREG... + d pr extproc('LIBSSH2_SFTP_S_ISREG') + d like(libssh2_Cint) + d permissions value like(libssh2_Culong) + + * C macro implementation. + d LIBSSH2_SFTP_S_ISDIR... + d pr extproc('LIBSSH2_SFTP_S_ISDIR') + d like(libssh2_Cint) + d permissions value like(libssh2_Culong) + + * C macro implementation. + d LIBSSH2_SFTP_S_ISCHR... + d pr extproc('LIBSSH2_SFTP_S_ISCHR') + d like(libssh2_Cint) + d permissions value like(libssh2_Culong) + + * C macro implementation. + d LIBSSH2_SFTP_S_ISBLK... + d pr extproc('LIBSSH2_SFTP_S_ISBLK') + d like(libssh2_Cint) + d permissions value like(libssh2_Culong) + + * C macro implementation. + d LIBSSH2_SFTP_S_ISFIFO... + d pr extproc('LIBSSH2_SFTP_S_ISFIFO') + d like(libssh2_Cint) + d permissions value like(libssh2_Culong) + + * C macro implementation. + d LIBSSH2_SFTP_S_ISSOCK... + d pr extproc('LIBSSH2_SFTP_S_ISSOCK') + d like(libssh2_Cint) + d permissions value like(libssh2_Culong) + + * SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open()) + * Danger will robinson... APPEND doesn't have any effect on OpenSSH + * servers. + d LIBSSH2_FXF_READ... + d c X'00000001' + d LIBSSH2_FXF_WRITE... + d c X'00000002' + d LIBSSH2_FXF_APPEND... + d c X'00000004' + d LIBSSH2_FXF_CREAT... + d c X'00000008' + d LIBSSH2_FXF_TRUNC... + d c X'00000010' + d LIBSSH2_FXF_EXCL... + d c X'00000020' + + * SFTP Status Codes (returned by libssh2_sftp_last_error()). + d LIBSSH2_FX_OK... + d c 0 + d LIBSSH2_FX_EOF... + d c 1 + d LIBSSH2_FX_NO_SUCH_FILE... + d c 2 + d LIBSSH2_FX_PERMISSION_DENIED... + d c 3 + d LIBSSH2_FX_FAILURE... + d c 4 + d LIBSSH2_FX_BAD_MESSAGE... + d c 5 + d LIBSSH2_FX_NO_CONNECTION... + d c 6 + d LIBSSH2_FX_CONNECTION_LOST... + d c 7 + d LIBSSH2_FX_OP_UNSUPPORTED... + d c 8 + d LIBSSH2_FX_INVALID_HANDLE... + d c 9 + d LIBSSH2_FX_NO_SUCH_PATH... + d c 10 + d LIBSSH2_FX_FILE_ALREADY_EXISTS... + d c 11 + d LIBSSH2_FX_WRITE_PROTECT... + d c 12 + d LIBSSH2_FX_NO_MEDIA... + d c 13 + d LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM... + d c 14 + d LIBSSH2_FX_QUOTA_EXCEEDED... + d c 15 + d LIBSSH2_FX_UNKNOWN_PRINCIPAL... + d c 16 + d LIBSSH2_FX_LOCK_CONFLICT... + d c 17 + d LIBSSH2_FX_DIR_NOT_EMPTY... + d c 18 + d LIBSSH2_FX_NOT_A_DIRECTORY... + d c 19 + d LIBSSH2_FX_INVALID_FILENAME... + d c 20 + d LIBSSH2_FX_LINK_LOOP... + d c 21 + + * Returned by any function that would block during a read/write operation. + d LIBSSH2SFTP_EAGAIN... + d c -37 + + * SFTP API. + d libssh2_sftp_init... + d pr * extproc('libssh2_sftp_init') LIBSSH2_SFTP * + d session * value LIBSSH2_SESSION * + + d libssh2_sftp_shutdown... + d pr extproc('libssh2_sftp_shutdown') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + + d libssh2_sftp_last_error... + d pr extproc('libssh2_sftp_last_error') + d like(libssh2_Culong) + d sftp * value LIBSSH2_SFTP * + + d libssh2_sftp_get_channel... + d pr * extproc('libssh2_sftp_get_channel') LIBSSH2_CHANNEL * + d sftp * value LIBSSH2_SFTP * + + * File / Directory Ops. + d libssh2_sftp_open_ex... + d pr * extproc('libssh2_sftp_open_ex') LIBSSH2_SFTP_HANDLE* + d sftp * value LIBSSH2_SFTP * + d filename * value options(*string) const char * + d filename_len value like(libssh2_Cuint) + d flags value like(libssh2_Culong) + d mode value like(libssh2_Clong) + d open_type value like(libssh2_Cint) + + * C macro implementation. + d libssh2_sftp_open... + d pr * extproc('libssh2_sftp_open') LIBSSH2_SFTP_HANDLE + d * + d sftp * value LIBSSH2_SFTP * + d filename * value options(*string) const char * + d flags value like(libssh2_Culong) + d mode value like(libssh2_Clong) + + * C macro libssh2_sftp_opendir implementation. + * Renamed to avoid upper/lower case name clash. + d libssh2_sftp_open_dir... + d pr * extproc('libssh2_sftp_opendir') LIBSSH2_SFTP_HANDLE + d * + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + + d libssh2_sftp_read... + d pr extproc('libssh2_sftp_read') + d like(libssh2_Cssize_t) + d handle * value LIBSSH2_SFTP_HANDLE* + d buffer * value options(*string) char * + d buffer_maxlen value like(libssh2_Csize_t) + + d libssh2_sftp_readdir_ex... + d pr extproc('libssh2_sftp_readdir_ex') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + d buffer * value char * + d buffer_maxlen value like(libssh2_Csize_t) + d longentry * value char * + d longentry_maxlen... + d value like(libssh2_Csize_t) + d attrs * value LIBSSH2_SFTP_... + d ATTRIBUTES * + + * C macro implementation. + d libssh2_sftp_readdir... + d pr extproc('libssh2_sftp_readdir') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + d buffer * value char * + d buffer_maxlen value like(libssh2_Csize_t) + d attrs * value LIBSSH2_SFTP_... + d ATTRIBUTES * + + d libssh2_sftp_write... + d pr extproc('libssh2_sftp_write') + d like(libssh2_Cssize_t) + d handle * value LIBSSH2_SFTP_HANDLE* + d buffer * value options(*string) const char * + d count value like(libssh2_Csize_t) + + d libssh2_sftp_fsync... + d pr extproc('libssh2_sftp_fsync') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + + d libssh2_sftp_close_handle... + d pr extproc('libssh2_sftp_close_handle') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + + * C macro implementation. + d libssh2_sftp_close... + d pr extproc('libssh2_sftp_close_handle') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + + * C macro implementation. + d libssh2_sftp_closedir... + d pr extproc('libssh2_sftp_close_handle') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + + d libssh2_sftp_seek... + d pr extproc('libssh2_sftp_seek') + d handle * value LIBSSH2_SFTP_HANDLE* + d offset value like(libssh2_Csize_t) + + d libssh2_sftp_seek64... + d pr extproc('libssh2_sftp_seek64') + d handle * value LIBSSH2_SFTP_HANDLE* + d offset value like(libssh2_uint64_t) + + * C macro implementation. + d libssh2_sftp_rewind... + d pr extproc('libssh2_sftp_rewind') + d handle * value LIBSSH2_SFTP_HANDLE* + + d libssh2_sftp_tell... + d pr extproc('libssh2_sftp_tell') + d like(libssh2_Csize_t) + d handle * value LIBSSH2_SFTP_HANDLE* + + d libssh2_sftp_tell64... + d pr extproc('libssh2_sftp_tell64') + d like(libssh2_uint64_t) + d handle * value LIBSSH2_SFTP_HANDLE* + + d libssh2_sftp_fstat_ex... + d pr extproc('libssh2_sftp_fstat_ex') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + d attrs * value LIBSSH2_SFTP_... + d ATTRIBUTES * + d setstat value like(libssh2_Cint) + + * C macro implementation. + d libssh2_sftp_fstat... + d pr extproc('libssh2_sftp_fstat') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + d attrs * value LIBSSH2_SFTP_... + d ATTRIBUTES * + + * C macro implementation. + d libssh2_sftp_fsetstat... + d pr extproc('libssh2_sftp_fsetstat') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + d attrs * value LIBSSH2_SFTP_... + d ATTRIBUTES * + + * Miscellaneous Ops. + d libssh2_sftp_rename_ex... + d pr extproc('libssh2_sftp_rename_ex') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d source_filename... + d * value options(*string) const char * + d source_filename_len... + d value like(libssh2_Cuint) + d dest_filename * value options(*string) const char * + d dest_filename_len... + d value like(libssh2_Cuint) + d flags value like(libssh2_Clong) + + * C macro implementation. + d libssh2_sftp_rename... + d pr extproc('libssh2_sftp_rename') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d source_filename... + d * value options(*string) const char * + d dest_filename * value options(*string) const char * + + d libssh2_sftp_unlink_ex... + d pr extproc('libssh2_sftp_unlink_ex') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d filename * value options(*string) const char * + d filename_len value like(libssh2_Cuint) + + * C macro implementation. + d libssh2_sftp_unlink... + d pr extproc('libssh2_sftp_unlink') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d filename * value options(*string) const char * + + d libssh2_sftp_fstatvfs... + d pr extproc('libssh2_sftp_fstatvfs') + d like(libssh2_Cint) + d handle * value LIBSSH2_SFTP_HANDLE* + d st * value LIBSSH2_SFTP_STATVFS + d * + + d libssh2_sftp_statvfs... + d pr extproc('libssh2_sftp_statvfs') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d path_len value like(libssh2_Csize_t) + d st * value LIBSSH2_SFTP_STATVFS + d * + + d libssh2_sftp_mkdir_ex... + d pr extproc('libssh2_sftp_mkdir_ex') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d path_len value like(libssh2_Cuint) + d mode value like(libssh2_Clong) + + * C macro implementation. + d libssh2_sftp_mkdir... + d pr extproc('libssh2_sftp_mkdir') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d mode value like(libssh2_Clong) + + d libssh2_sftp_rmdir_ex... + d pr extproc('libssh2_sftp_rmdir_ex') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d path_len value like(libssh2_Cuint) + + * C macro implementation. + d libssh2_sftp_rmdir... + d pr extproc('libssh2_sftp_rmdir') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + + d libssh2_sftp_stat_ex... + d pr extproc('libssh2_sftp_stat_ex') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d path_len value like(libssh2_Cuint) + d stat_type value like(libssh2_Cint) + d attrs * value LIBSSH2_SFTP_... + d ATTRIBUTES * + + * C macro libssh2_sftp_stat implementation. + * Renamed to avoid upper/lower case name clash. + d libssh2_sftp_get_stat... + d pr extproc('libssh2_sftp_stat') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d attrs * value LIBSSH2_SFTP_... + d ATTRIBUTES * + + * C macro libssh2_sftp_lstat implementation. + * Renamed to avoid upper/lower case name clash. + d libssh2_sftp_get_lstat... + d pr extproc('libssh2_sftp_lstat') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d attrs * value LIBSSH2_SFTP_... + d ATTRIBUTES * + + * C macro libssh2_sftp_setstat implementation. + * Renamed to avoid upper/lower case name clash. + d libssh2_sftp_set_stat... + d pr extproc('libssh2_sftp_setstat') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d attrs * value LIBSSH2_SFTP_... + d ATTRIBUTES * + + d libssh2_sftp_symlink_ex... + d pr extproc('libssh2_sftp_symlink_ex') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d path_len value like(libssh2_Cuint) + d target * value options(*string) char * + d target_len value like(libssh2_Cuint) + d link_type value like(libssh2_Cint) + + * C macro libssh2_sftp_symlink implementation. + * Renamed to avoid upper/lower case name clash. + d libssh2_sftp_sym_link... + d pr extproc('libssh2_sftp_symlink') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d orig * value options(*string) const char * + d linkpath * value options(*string) char * + + * C macro libssh2_sftp_readlink implementation. + * Renamed to avoid upper/lower case name clash. + d libssh2_sftp_read_link... + d pr extproc('libssh2_sftp_readlink') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d target * value char * + d maxlen value like(libssh2_Cuint) + + * C macro libssh2_sftp_realpath implementation. + * Renamed to avoid upper/lower case name clash. + d libssh2_sftp_real_path... + d pr extproc('libssh2_sftp_realpath') + d like(libssh2_Cint) + d sftp * value LIBSSH2_SFTP * + d path * value options(*string) const char * + d target * value char * + d maxlen value like(libssh2_Cuint) + + /endif LIBSSH2_SFTP_H_ diff --git a/libssh2/os400/macros.h b/libssh2/os400/macros.h new file mode 100644 index 000000000..408b98d01 --- /dev/null +++ b/libssh2/os400/macros.h @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBSSH2_MACROS_H_ +#define LIBSSH2_MACROS_H_ + +#include "libssh2.h" +#include "libssh2_publickey.h" +#include "libssh2_sftp.h" + +/* + * Dummy prototypes to generate wrapper procedures to C macros. + * This is a helper for languages without a clever preprocessor (ILE/RPG). + */ + +LIBSSH2_API LIBSSH2_SESSION * libssh2_session_init(void); +LIBSSH2_API int libssh2_session_disconnect(LIBSSH2_SESSION *session, + const char *description); +LIBSSH2_API int libssh2_userauth_password(LIBSSH2_SESSION *session, + const char *username, + const char *password); +LIBSSH2_API int +libssh2_userauth_publickey_fromfile(LIBSSH2_SESSION *session, + const char *username, + const char *publickey, + const char *privatekey, + const char *passphrase); +LIBSSH2_API int +libssh2_userauth_hostbased_fromfile(LIBSSH2_SESSION *session, + const char *username, + const char *publickey, + const char *privatekey, + const char *passphrase, + const char *hostname); +LIBSSH2_API int +libssh2_userauth_keyboard_interactive(LIBSSH2_SESSION* session, + const char *username, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC( + (*response_callback))); +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_open_session(LIBSSH2_SESSION *session); +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_direct_tcpip(LIBSSH2_SESSION *session, const char *host, + int port); +LIBSSH2_API LIBSSH2_LISTENER * +libssh2_channel_forward_listen(LIBSSH2_SESSION *session, int port); +LIBSSH2_API int +libssh2_channel_setenv(LIBSSH2_CHANNEL *channel, + const char *varname, const char *value); +LIBSSH2_API int +libssh2_channel_request_pty(LIBSSH2_CHANNEL *channel, const char *term); +LIBSSH2_API int +libssh2_channel_request_pty_size(LIBSSH2_CHANNEL *channel, + int width, int height); +LIBSSH2_API int +libssh2_channel_x11_req(LIBSSH2_CHANNEL *channel, int screen_number); +LIBSSH2_API int +libssh2_channel_shell(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int +libssh2_channel_exec(LIBSSH2_CHANNEL *channel, const char *command); +LIBSSH2_API int +libssh2_channel_subsystem(LIBSSH2_CHANNEL *channel, const char *subsystem); +LIBSSH2_API ssize_t +libssh2_channel_read(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen); +LIBSSH2_API ssize_t +libssh2_channel_read_stderr(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen); +LIBSSH2_API unsigned long +libssh2_channel_window_read(LIBSSH2_CHANNEL *channel); +LIBSSH2_API ssize_t +libssh2_channel_write(LIBSSH2_CHANNEL *channel, const char *buf, size_t buflen); +LIBSSH2_API ssize_t +libssh2_channel_write_stderr(LIBSSH2_CHANNEL *channel, + const char *buf, size_t buflen); +LIBSSH2_API unsigned long +libssh2_channel_window_write(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_flush(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_flush_stderr(LIBSSH2_CHANNEL *channel); +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send(LIBSSH2_SESSION *session, + const char *path, int mode, libssh2_int64_t size); + +LIBSSH2_API int +libssh2_publickey_add(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, + const unsigned char *blob, unsigned long blob_len, + char overwrite, unsigned long num_attrs, + const libssh2_publickey_attribute attrs[]); +LIBSSH2_API int +libssh2_publickey_remove(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, + const unsigned char *blob, unsigned long blob_len); + +LIBSSH2_API int LIBSSH2_SFTP_S_ISLNK(unsigned long permissions); +LIBSSH2_API int LIBSSH2_SFTP_S_ISREG(unsigned long permissions); +LIBSSH2_API int LIBSSH2_SFTP_S_ISDIR(unsigned long permissions); +LIBSSH2_API int LIBSSH2_SFTP_S_ISCHR(unsigned long permissions); +LIBSSH2_API int LIBSSH2_SFTP_S_ISBLK(unsigned long permissions); +LIBSSH2_API int LIBSSH2_SFTP_S_ISFIFO(unsigned long permissions); +LIBSSH2_API int LIBSSH2_SFTP_S_ISSOCK(unsigned long permissions); +LIBSSH2_API LIBSSH2_SFTP_HANDLE * +libssh2_sftp_open(LIBSSH2_SFTP *sftp, const char *filename, + unsigned long flags, long mode); +LIBSSH2_API LIBSSH2_SFTP_HANDLE * +libssh2_sftp_opendir(LIBSSH2_SFTP *sftp, const char *path); +LIBSSH2_API int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, + char *buffer, size_t buffer_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +LIBSSH2_API int libssh2_sftp_close(LIBSSH2_SFTP_HANDLE *handle); +LIBSSH2_API int libssh2_sftp_closedir(LIBSSH2_SFTP_HANDLE *handle); +LIBSSH2_API void libssh2_sftp_rewind(LIBSSH2_SFTP_HANDLE *handle); +LIBSSH2_API int libssh2_sftp_fstat(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +LIBSSH2_API int libssh2_sftp_fsetstat(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +LIBSSH2_API int libssh2_sftp_rename(LIBSSH2_SFTP *sftp, + const char *source_filename, + const char *dest_filename); +LIBSSH2_API int libssh2_sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename); +LIBSSH2_API int libssh2_sftp_mkdir(LIBSSH2_SFTP *sftp, + const char *path, long mode); +LIBSSH2_API int libssh2_sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path); +LIBSSH2_API int libssh2_sftp_stat(LIBSSH2_SFTP *sftp, const char *path, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +LIBSSH2_API int libssh2_sftp_lstat(LIBSSH2_SFTP *sftp, const char *path, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +LIBSSH2_API int libssh2_sftp_setstat(LIBSSH2_SFTP *sftp, const char *path, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +LIBSSH2_API int libssh2_sftp_symlink(LIBSSH2_SFTP *sftp, const char *orig, + char *linkpath); +LIBSSH2_API int libssh2_sftp_readlink(LIBSSH2_SFTP *sftp, const char *path, + char *target, unsigned int maxlen); +LIBSSH2_API int libssh2_sftp_realpath(LIBSSH2_SFTP *sftp, const char *path, + char *target, unsigned int maxlen); + +#endif diff --git a/libssh2/os400/make-include.sh b/libssh2/os400/make-include.sh new file mode 100644 index 000000000..2cb7b7260 --- /dev/null +++ b/libssh2/os400/make-include.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# +# Installation of the header files in the OS/400 library. +# + +SCRIPTDIR=`dirname "${0}"` +. "${SCRIPTDIR}/initscript.sh" +cd "${TOPDIR}/include" + + +# Create the OS/400 source program file for the header files. + +SRCPF="${LIBIFSNAME}/H.FILE" + +if action_needed "${SRCPF}" +then CMD="CRTSRCPF FILE(${TARGETLIB}/H) RCDLEN(112)" + CMD="${CMD} CCSID(${TGTCCSID}) TEXT('libssh2: Header files')" + system "${CMD}" +fi + + +# Create the IFS directory for the header files. + +IFSINCLUDE="${IFSDIR}/include" + +if action_needed "${IFSINCLUDE}" +then mkdir -p "${IFSINCLUDE}" +fi + + +copy_hfile() + +{ + destfile="${1}" + srcfile="${2}" + shift + shift + sed -e '1i\ +#pragma datamodel(P128)\ +' "${@}" -e '$a\ +#pragma datamodel(pop)\ +' < "${srcfile}" > "${destfile}" +} + +# Copy the header files. + +for HFILE in *.h "${TOPDIR}/os400/libssh2_ccsid.h" +do DEST="${SRCPF}/`db2_name \"${HFILE}\"`.MBR" + + if action_needed "${DEST}" "${HFILE}" + then copy_hfile "${DEST}" "${HFILE}" + IFSDEST="${IFSINCLUDE}/`basename \"${HFILE}\"`" + rm -f "${IFSDEST}" + ln -s "${DEST}" "${IFSDEST}" + fi +done diff --git a/libssh2/os400/make-rpg.sh b/libssh2/os400/make-rpg.sh new file mode 100644 index 000000000..c8a264724 --- /dev/null +++ b/libssh2/os400/make-rpg.sh @@ -0,0 +1,92 @@ +#!/bin/sh +# +# Installation of the ILE/RPG header files in the OS/400 library. +# + +SCRIPTDIR=`dirname "${0}"` +. "${SCRIPTDIR}/initscript.sh" +cd "${TOPDIR}/os400/libssh2rpg" + + +# Create the OS/400 source program file for the ILE/RPG header files. + +SRCPF="${LIBIFSNAME}/LIBSSH2RPG.FILE" + +if action_needed "${SRCPF}" +then CMD="CRTSRCPF FILE(${TARGETLIB}/LIBSSH2RPG) RCDLEN(112)" + CMD="${CMD} CCSID(${TGTCCSID}) TEXT('libssh2: ILE/RPG header files')" + system "${CMD}" +fi + + +# Map file names to DB2 name syntax. + +for HFILE in *.rpgle *.rpgle.in +do NAME="`basename \"${HFILE}\" .in`" + VAR="`basename \"${NAME}\" .rpgle`" + VAL="`db2_name \"${NAME}\"`" + + eval "VAR_${VAR}=\"${VAL}\"" + echo "${VAR} s/${VAR}/${VAL}/g" +done > tmpsubstfile1 + +# Order substitution commands so that a prefix appears after all +# file names beginning with the prefix. + +sort -r tmpsubstfile1 | sed 's/^[^ ]*[ ]*//' > tmpsubstfile2 + + +change_include() + +{ + sed -e '\#^....../include *"libssh2rpg/#{' \ + -e 's///' \ + -e 's/".*//' \ + -f tmpsubstfile2 \ + -e 's#.*# /include libssh2rpg,&#' \ + -e '}' +} + + +# Create the IFS directory for the ILE/RPG header files. + +RPGIFSDIR="${IFSDIR}/include/libssh2rpg" + +if action_needed "${RPGIFSDIR}" +then mkdir -p "${RPGIFSDIR}" +fi + +# Copy the header files to IFS ILE/RPG include directory. +# Copy them with include path editing to the DB2 library. + +for HFILE in *.rpgle *.rpgle.in +do IFSCMD="cat \"${HFILE}\"" + DB2CMD="change_include < \"${HFILE}\"" + IFSFILE="`basename \"${HFILE}\" .in`" + + case "${HFILE}" in + + *.in) IFSCMD="${IFSCMD} | versioned_copy" + DB2CMD="${DB2CMD} | versioned_copy" + ;; + esac + + IFSDEST="${RPGIFSDIR}/${IFSFILE}" + + if action_needed "${IFSDEST}" "${HFILE}" + then eval "${IFSCMD}" > "${IFSDEST}" + fi + + eval DB2MBR="\"\${VAR_`basename \"${IFSDEST}\" .rpgle`}\"" + DB2DEST="${SRCPF}/${DB2MBR}.MBR" + + if action_needed "${DB2DEST}" "${HFILE}" + then eval "${DB2CMD}" | change_include > tmphdrfile + + # Need to translate to target CCSID. + + CMD="CPY OBJ('`pwd`/tmphdrfile') TOOBJ('${DB2DEST}')" + CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)" + system "${CMD}" + fi +done diff --git a/libssh2/os400/make-src.sh b/libssh2/os400/make-src.sh new file mode 100644 index 000000000..2e9a3c430 --- /dev/null +++ b/libssh2/os400/make-src.sh @@ -0,0 +1,208 @@ +#!/bin/sh +# +# libssh2 compilation script for the OS/400. +# + +SCRIPTDIR=`dirname "${0}"` +. "${SCRIPTDIR}/initscript.sh" +cd "${TOPDIR}/src" + + +# Function to extract external prototypes from header files. +# Input: concatenated header files. +# Output: external prototypes, one per (long) line. + +extproto() +{ + sed -e 'x;G;s/^\n//;s/\n/ /g' \ + -e 's#[[:space:]]*/\*[^*]*\(\*\([^/*][^*]*\)\{0,1\}\)*\*/[[:space:]]*##g' \ + -e 'h' \ + -e '/\/\*/!{' \ + -e '/^#/{s/^.*[^\\]$//;h;d' \ + -e '}' \ + -e 's/[{}]/;/g;s/\\$//' \ + -e ':loop1' \ + -e '/;/{' \ + -e 's/^[^;]*;//;x;s/;.*//' \ + -e '/^[[:space:]]*LIBSSH2_API[[:space:]].*(/{' \ + -e 's/^[[:space:]]*LIBSSH2_API[[:space:]]*//' \ + -e 's/[[:space:]]*$//' \ + -e 's/[[:space:]][[:space:]]*/ /g' \ + -e 'p' \ + -e '}' \ + -e 'g;bloop1' \ + -e '}' \ + -e '}' \ + -n +} + +# Need to have IFS access to the mih/modasa header file. + +if action_needed modasa.mih '/QSYS.LIB/QSYSINC.LIB/MIH.FILE/MODASA.MBR' +then rm -f modasa.mih + ln -s '/QSYS.LIB/QSYSINC.LIB/MIH.FILE/MODASA.MBR' modasa.mih +fi + + +# Create and compile the identification source file. + +echo '#pragma comment(user, "libssh2 version '"${LIBSSH2_VERSION}"'")' > os400.c +echo '#pragma comment(user, __DATE__)' >> os400.c +echo '#pragma comment(user, __TIME__)' >> os400.c +echo '#pragma comment(copyright, "See COPYING file. OS/400 version by P. Monnerat")' >> os400.c +make_module OS400 os400.c +LINK= # No need to rebuild service program yet. +MODULES= + + +# Generate the procedures implementing macros. + +if action_needed macros.c "${TOPDIR}/os400/macros.h" +then ( + echo '#include "libssh2_publickey.h"' + echo '#include "libssh2_sftp.h"' + extproto < "${TOPDIR}/os400/macros.h" | + sed -e 'h;s/^[^(]*[ *]\([^ (]*\) *(.*/\1/' \ + -e 's/.*/#pragma map(_&, "&")/;p' \ + -e 'g;s/^\([^(]*[ *]\)\([^ (]*\)\( *(.*\)/\1_\2\3 {/;p' \ + -e 'g;s/^[^(]*(\(.*\))$/,\1,/;s/[^A-Za-z0-9_,]/ /g' \ + -e 's/ *,/,/g;s/,[^,]* \([^ ,]*\)/,\1/g' \ + -e 's/ //g;s/^,void,$/,,/' \ + -e 's/^,\(.*\),$/(\1); }/;s/,/, /g' \ + -e 'x;s/(.*//;s/ *$//;G;s/\n//g' \ + -e 's/^void\([ *]\)/\1/;s/^ *//' \ + -e 's/^[^(]*[ *]\([A-Za-z][A-Za-z0-9_]* *(\)/return \1/' \ + -e 's/.*/ &/' + ) > macros.c +fi + +# Get source list. + +cat ../Makefile.inc ../Makefile.os400qc3.inc | + sed -e ':begin' \ + -e '/\\$/{' \ + -e 's/\\$/ /' \ + -e 'N' \ + -e 'bbegin' \ + -e '}' \ + -e 's/\n//g' \ + -e 's/[[:space:]]*$//' \ + -e 's/^\([A-Za-z][A-Za-z0-9_]*\)[[:space:]]*=[[:space:]]*\(.*\)/\1="\2"/' \ + -e 's/\$(\([A-Za-z][A-Za-z0-9_]*\))/${\1}/g' \ + > tmpscript.sh +. ./tmpscript.sh + + +# Compile the sources into modules. + +INCLUDES="'`pwd`'" + +for SRC in "${TOPDIR}/os400/os400sys.c" "${TOPDIR}/os400/ccsid.c" \ + ${CSOURCES} ${CRYPTO_CSOURCES} macros.c +do MODULE=`db2_name "${SRC}"` + make_module "${MODULE}" "${SRC}" +done + + +# If needed, (re)create the static binding directory. + +if action_needed "${LIBIFSNAME}/${STATBNDDIR}.BNDDIR" +then LINK=YES +fi + +if [ "${LINK}" ] +then rm -rf "${LIBIFSNAME}/${STATBNDDIR}.BNDDIR" + CMD="CRTBNDDIR BNDDIR(${TARGETLIB}/${STATBNDDIR})" + CMD="${CMD} TEXT('libssh2 API static binding directory')" + system "${CMD}" + + for MODULE in ${MODULES} + do CMD="ADDBNDDIRE BNDDIR(${TARGETLIB}/${STATBNDDIR})" + CMD="${CMD} OBJ((${TARGETLIB}/${MODULE} *MODULE))" + system "${CMD}" + done + +# V6R1M0 does not list system service program QC3PBEXT in the +# implicit binding directory: thus we add it here in ours. + + CMD="ADDBNDDIRE BNDDIR(${TARGETLIB}/${STATBNDDIR})" + CMD="${CMD} OBJ((QSYS/QC3PBEXT *SRVPGM))" + system "${CMD}" +fi + + +# The exportation file for service program creation must be in a DB2 +# source file, so make sure it exists. + +if action_needed "${LIBIFSNAME}/TOOLS.FILE" +then CMD="CRTSRCPF FILE(${TARGETLIB}/TOOLS) RCDLEN(112)" + CMD="${CMD} TEXT('libssh2: build tools')" + system "${CMD}" +fi + + +# Gather the list of symbols to export. + +EXPORTS=`cat "${TOPDIR}"/include/*.h "${TOPDIR}/os400/macros.h" \ + "${TOPDIR}/os400/libssh2_ccsid.h" | + extproto | + sed -e 's/(.*//;s/[^A-Za-z0-9_]/ /g;s/ *$//;s/^.* //'` + +# Create the service program exportation file in DB2 member if needed. + +BSF="${LIBIFSNAME}/TOOLS.FILE/BNDSRC.MBR" + +if action_needed "${BSF}" Makefile.am +then LINK=YES +fi + +if [ "${LINK}" ] +then echo " STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('LIBSSH2_${SONAME}')" \ + > "${BSF}" + for EXPORT in ${EXPORTS} + do echo ' EXPORT SYMBOL("'"${EXPORT}"'")' >> "${BSF}" + done + + echo ' ENDPGMEXP' >> "${BSF}" +fi + + +# Build the service program if needed. + +if action_needed "${LIBIFSNAME}/${SRVPGM}.SRVPGM" +then LINK=YES +fi + +if [ "${LINK}" ] +then CMD="CRTSRVPGM SRVPGM(${TARGETLIB}/${SRVPGM})" + CMD="${CMD} SRCFILE(${TARGETLIB}/TOOLS) SRCMBR(BNDSRC)" + CMD="${CMD} MODULE(${TARGETLIB}/OS400)" + CMD="${CMD} BNDDIR(${TARGETLIB}/${STATBNDDIR}" + if [ "${WITH_ZLIB}" != 0 ] + then CMD="${CMD} ${ZLIB_LIB}/${ZLIB_BNDDIR}" + liblist -a "${ZLIB_LIB}" + fi + CMD="${CMD})" + CMD="${CMD} BNDSRVPGM(QADRTTS)" + CMD="${CMD} TEXT('libssh2 API library')" + CMD="${CMD} TGTRLS(${TGTRLS})" + system "${CMD}" + LINK=YES +fi + + +# If needed, (re)create the dynamic binding directory. + +if action_needed "${LIBIFSNAME}/${DYNBNDDIR}.BNDDIR" +then LINK=YES +fi + +if [ "${LINK}" ] +then rm -rf "${LIBIFSNAME}/${DYNBNDDIR}.BNDDIR" + CMD="CRTBNDDIR BNDDIR(${TARGETLIB}/${DYNBNDDIR})" + CMD="${CMD} TEXT('libssh2 API dynamic binding directory')" + system "${CMD}" + CMD="ADDBNDDIRE BNDDIR(${TARGETLIB}/${DYNBNDDIR})" + CMD="${CMD} OBJ((*LIBL/${SRVPGM} *SRVPGM))" + system "${CMD}" +fi diff --git a/libssh2/os400/make.sh b/libssh2/os400/make.sh new file mode 100644 index 000000000..0c9e3decd --- /dev/null +++ b/libssh2/os400/make.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# libssh2 compilation script for the OS/400. +# +# +# This is a shell script since make is not a standard component of OS/400. + +SCRIPTDIR=`dirname "${0}"` +. "${SCRIPTDIR}/initscript.sh" +cd "${TOPDIR}" + + +# Create the OS/400 library if it does not exist. + +if action_needed "${LIBIFSNAME}" +then CMD="CRTLIB LIB(${TARGETLIB}) TEXT('libssh2: SSH2 protocol API')" + system "${CMD}" +fi + + +# Create the DOCS source file if it does not exist. + +if action_needed "${LIBIFSNAME}/DOCS.FILE" +then CMD="CRTSRCPF FILE(${TARGETLIB}/DOCS) RCDLEN(240)" + CMD="${CMD} CCSID(${TGTCCSID}) TEXT('Documentation texts')" + system "${CMD}" +fi + + +# Copy some documentation files if needed. + +for TEXT in "${TOPDIR}/COPYING" "${SCRIPTDIR}/README400" \ + "${TOPDIR}/NEWS" "${TOPDIR}/README" "${TOPDIR}/docs/AUTHORS" \ + "${TOPDIR}/docs/BINDINGS" +do MEMBER="${LIBIFSNAME}/DOCS.FILE/`db2_name \"${TEXT}\"`.MBR" + + if action_needed "${MEMBER}" "${TEXT}" + then CMD="CPY OBJ('${TEXT}') TOOBJ('${MEMBER}') TOCCSID(${TGTCCSID})" + CMD="${CMD} DTAFMT(*TEXT) REPLACE(*YES)" + system "${CMD}" + fi +done + + +# Build in each directory. + +for SUBDIR in include rpg src +do "${SCRIPTDIR}/make-${SUBDIR}.sh" +done diff --git a/libssh2/os400/os400sys.c b/libssh2/os400/os400sys.c new file mode 100644 index 000000000..db67876be --- /dev/null +++ b/libssh2/os400/os400sys.c @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +/* OS/400 additional support. */ + +#define LIBSSH2_DISABLE_QADRT_EXT + +#include "libssh2_priv.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef LIBSSH2_HAVE_ZLIB +# include +#endif + + +/** +*** QADRT OS/400 ASCII runtime defines only the most used procedures, but +*** a lot of them are not supported. This module implements +*** ASCII wrappers for those that are used by libssh2, but not +*** defined by QADRT. +**/ + +#pragma convert(37) /* Restore EBCDIC. */ + + +static int +convert_sockaddr(struct sockaddr_storage * dstaddr, + const struct sockaddr * srcaddr, int srclen) + +{ + const struct sockaddr_un * srcu; + struct sockaddr_un * dstu; + unsigned int i; + unsigned int dstsize; + + /* Convert a socket address into job CCSID, if needed. */ + + if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) + + sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) { + errno = EINVAL; + return -1; + } + + memcpy((char *) dstaddr, (char *) srcaddr, srclen); + + switch (srcaddr->sa_family) { + + case AF_UNIX: + srcu = (const struct sockaddr_un *) srcaddr; + dstu = (struct sockaddr_un *) dstaddr; + dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path); + srclen -= offsetof(struct sockaddr_un, sun_path); + i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen); + dstu->sun_path[i] = '\0'; + i += offsetof(struct sockaddr_un, sun_path); + srclen = i; + } + + return srclen; +} + + +int +_libssh2_os400_connect(int sd, struct sockaddr * destaddr, int addrlen) + +{ + int i; + struct sockaddr_storage laddr; + + i = convert_sockaddr(&laddr, destaddr, addrlen); + + if(i < 0) + return -1; + + return connect(sd, (struct sockaddr *) &laddr, i); +} + + +int +_libssh2_os400_vsnprintf(char *dst, size_t len, const char *fmt, va_list args) +{ + size_t l = 4096; + int i; + char *buf; + + if (!dst || !len) { + errno = EINVAL; + return -1; + } + + if (l < len) + l = len; + + buf = alloca(l); + + if (!buf) { + errno = ENOMEM; + return -1; + } + + i = vsprintf(buf, fmt, args); + + if (i < 0) + return i; + + if (--len > i) + len = i; + + if (len) + memcpy(dst, buf, len); + + dst[len] = '\0'; + return len; +} + +/* VARARGS3 */ +int +_libssh2_os400_snprintf(char *dst, size_t len, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = _libssh2_os400_vsnprintf(dst, len, fmt, args); + va_end(args); + return ret; +} + + +#ifdef LIBSSH2_HAVE_ZLIB +int +_libssh2_os400_inflateInit_(z_streamp strm, + const char *version, int stream_size) +{ + char *ebcversion; + int i; + + if (!version) + return Z_VERSION_ERROR; + i = strlen(version); + ebcversion = alloca(i + 1); + if (!ebcversion) + return Z_VERSION_ERROR; + i = QadrtConvertA2E(ebcversion, version, i, i - 1); + ebcversion[i] = '\0'; + return inflateInit_(strm, ebcversion, stream_size); +} + +int +_libssh2_os400_deflateInit_(z_streamp strm, int level, + const char *version, int stream_size) +{ + char *ebcversion; + int i; + + if (!version) + return Z_VERSION_ERROR; + i = strlen(version); + ebcversion = alloca(i + 1); + if (!ebcversion) + return Z_VERSION_ERROR; + i = QadrtConvertA2E(ebcversion, version, i, i - 1); + ebcversion[i] = '\0'; + return deflateInit_(strm, level, ebcversion, stream_size); +} + +#endif diff --git a/libssh2/src/CMakeLists.txt b/libssh2/src/CMakeLists.txt new file mode 100644 index 000000000..6401acff2 --- /dev/null +++ b/libssh2/src/CMakeLists.txt @@ -0,0 +1,423 @@ +# Copyright (c) 2014 Alexander Lamaison +# +# Redistribution and use in source and binary forms, +# with or without modification, are permitted provided +# that the following conditions are met: +# +# Redistributions of source code must retain the above +# copyright notice, this list of conditions and the +# following disclaimer. +# +# 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. +# +# Neither the name of the copyright holder nor the names +# of any other contributors may be used to endorse or +# promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +# OF SUCH DAMAGE. + +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckFunctionExistsMayNeedLibrary) +include(CheckIncludeFiles) +include(CheckTypeSize) +include(CheckSymbolExists) +include(CheckNonblockingSocketSupport) +include(SocketLibraries) + +## Cryptography backend choice + +set(CRYPTO_BACKEND + "" + CACHE + STRING + "The backend to use for cryptography: OpenSSL, Libgcrypt or WinCNG, mbedTLS +or empty to try any available") + +# If the crypto backend was given, rather than searching for the first +# we are able to find, the find_package commands must abort configuration +# and report to the user. +if(CRYPTO_BACKEND) + set(SPECIFIC_CRYPTO_REQUIREMENT REQUIRED) +endif() + +if(CRYPTO_BACKEND STREQUAL "OpenSSL" OR NOT CRYPTO_BACKEND) + + find_package(OpenSSL ${SPECIFIC_CRYPTO_REQUIREMENT}) + + if(OPENSSL_FOUND) + set(CRYPTO_BACKEND "OpenSSL") + set(CRYPTO_SOURCES openssl.c openssl.h) + list(APPEND PRIVATE_COMPILE_DEFINITIONS LIBSSH2_OPENSSL) + list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${OPENSSL_INCLUDE_DIR}) + list(APPEND LIBRARIES ${OPENSSL_LIBRARIES}) + list(APPEND PC_REQUIRES_PRIVATE libssl libcrypto) + + if (WIN32) + # Statically linking to OpenSSL requires crypt32 for some Windows APIs. + # This should really be handled by FindOpenSSL.cmake. + list(APPEND LIBRARIES crypt32) + list(APPEND PC_LIBS -lcrypt32) + + find_file(DLL_LIBEAY32 + NAMES libeay32.dll crypto.dll + HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS} + PATH_SUFFIXES bin) + if (NOT DLL_LIBEAY32) + message(WARNING + "Unable to find OpenSSL libeay32 DLL, executables may not run") + endif() + + find_file(DLL_SSLEAY32 + NAMES ssleay32.dll ssl.dll + HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS} + PATH_SUFFIXES bin) + if (NOT DLL_SSLEAY32) + message(WARNING + "Unable to find OpenSSL ssleay32 DLL, executables may not run") + endif() + + if(DLL_LIBEAY32 AND DLL_SSLEAY32) + list(APPEND _RUNTIME_DEPENDENCIES ${DLL_LIBEAY32} ${DLL_SSLEAY32}) + endif() + endif() + + # Not all OpenSSL have AES-CTR functions. + set(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) + check_function_exists(EVP_aes_128_ctr HAVE_EVP_AES_128_CTR) + set(CMAKE_REQUIRED_LIBRARIES ${SAVE_CMAKE_REQUIRED_LIBRARIES}) + endif() +endif() + +if(CRYPTO_BACKEND STREQUAL "Libgcrypt" OR NOT CRYPTO_BACKEND) + + find_package(Libgcrypt ${SPECIFIC_CRYPTO_REQUIREMENT}) + + if(LIBGCRYPT_FOUND) + set(CRYPTO_BACKEND "Libgcrypt") + set(CRYPTO_SOURCES libgcrypt.c libgcrypt.h) + list(APPEND PRIVATE_COMPILE_DEFINITIONS LIBSSH2_LIBGCRYPT) + list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${LIBGCRYPT_INCLUDE_DIRS}) + list(APPEND LIBRARIES ${LIBGCRYPT_LIBRARIES}) + list(APPEND PC_LIBS -lgcrypt) + endif() +endif() + +if(CRYPTO_BACKEND STREQUAL "WinCNG" OR NOT CRYPTO_BACKEND) + + # The check actually compiles the header. This requires windows.h. + check_include_files("windows.h;bcrypt.h" HAVE_BCRYPT_H) + + if(HAVE_BCRYPT_H) + set(CRYPTO_BACKEND "WinCNG") + set(CRYPTO_SOURCES wincng.c wincng.h) + list(APPEND PRIVATE_COMPILE_DEFINITIONS LIBSSH2_WINCNG) + + set(HAVE_LIBCRYPT32 TRUE) + list(APPEND LIBRARIES bcrypt) + list(APPEND PC_LIBS -lbcrypt) + + check_include_files(ntdef.h HAVE_NTDEF_H) + check_include_files(ntstatus.h HAVE_NTSTATUS_H) + + # Reading keys from files is optional and depends on Wincrypt + check_include_files("windows.h;wincrypt.h" HAVE_WINCRYPT_H) + + if(HAVE_WINCRYPT_H) + list(APPEND LIBRARIES crypt32) + list(APPEND PC_LIBS -lcrypt32) + endif() + + elseif(${SPECIFIC_CRYPTO_REQUIREMENT} STREQUAL ${REQUIRED}) + message(FATAL_ERROR "WinCNG not available") + endif() +endif() + +if(CRYPTO_BACKEND STREQUAL "mbedTLS" OR NOT CRYPTO_BACKEND) + + find_package(mbedTLS ${SPECIFIC_CRYPTO_REQUIREMENT}) + + if(MBEDTLS_FOUND) + set(CRYPTO_BACKEND "mbedTLS") + set(CRYPTO_SOURCES mbedtls.c mbedtls.h) + list(APPEND PRIVATE_COMPILE_DEFINITIONS LIBSSH2_MBEDTLS) + list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${MBEDTLS_INCLUDE_DIR}) + list(APPEND LIBRARIES ${MBEDTLS_LIBRARIES}) + list(APPEND PC_LIBS -lmbedcrypto) + link_directories(${MBEDTLS_LIBRARY_DIR}) + endif() +endif() + +if(NOT CRYPTO_BACKEND) + message(FATAL_ERROR "No suitable cryptography backend found.") +endif() + +## Library definition + +include(GNUInstallDirs) +set(SOURCES + ${CRYPTO_SOURCES} + agent.c + channel.c + channel.h + comp.c + comp.h + crypt.c + crypto.h + global.c + hostkey.c + keepalive.c + kex.c + knownhost.c + libssh2_priv.h + mac.c + mac.h + misc.c + misc.h + packet.c + packet.h + pem.c + publickey.c + scp.c + session.c + session.h + sftp.c + sftp.h + transport.c + transport.h + userauth.c + userauth.h + version.c) + +if(WIN32) + list(APPEND SOURCES ${PROJECT_SOURCE_DIR}/win32/libssh2.rc) +endif() + +add_library(libssh2 ${SOURCES}) +# we want it to be called libssh2 on all platforms +set_target_properties(libssh2 PROPERTIES PREFIX "") + +target_compile_definitions(libssh2 PRIVATE ${PRIVATE_COMPILE_DEFINITIONS}) +target_include_directories(libssh2 + PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES} + PUBLIC + $ + $/${CMAKE_INSTALL_INCLUDEDIR}>) + +## Options + +option(CLEAR_MEMORY "Enable clearing of memory before being freed" ON) +if(CLEAR_MEMORY) + add_definitions(-DLIBSSH2_CLEAR_MEMORY) +endif(CLEAR_MEMORY) + +add_feature_info("Shared library" BUILD_SHARED_LIBS + "creating libssh2 as a shared library (.so/.dll)") + +option(ENABLE_ZLIB_COMPRESSION "Use zlib for compression") +add_feature_info(Compression ENABLE_ZLIB_COMPRESSION + "using zlib for compression") +if(ENABLE_ZLIB_COMPRESSION) + find_package(ZLIB REQUIRED) + + target_include_directories(libssh2 PRIVATE ${ZLIB_INCLUDE_DIRS}) + list(APPEND LIBRARIES ${ZLIB_LIBRARIES}) + list(APPEND PC_REQUIRES_PRIVATE zlib) + if(ZLIB_FOUND) + target_compile_definitions(libssh2 PRIVATE LIBSSH2_HAVE_ZLIB=1) + endif() +endif() + +option(ENABLE_CRYPT_NONE "Permit \"none\" cipher -- NOT RECOMMENDED") +add_feature_info("\"none\" cipher" ENABLE_CRYPT_NONE "") +if(ENABLE_CRYPT_NONE) + target_compile_definitions(libssh2 PRIVATE LIBSSH2_CRYPT_NONE=1) +endif() + +option(ENABLE_MAC_NONE "Permit \"none\" MAC -- NOT RECOMMMENDED") +add_feature_info("\"none\" MAC" ENABLE_MAC_NONE "") +if(ENABLE_MAC_NONE) + target_compile_definitions(libssh2 PRIVATE LIBSSH2_MAC_NONE=1) +endif() + +option(ENABLE_GEX_NEW + "Enable diffie-hellman-group-exchange-sha1 method" ON) +add_feature_info("diffie-hellman-group-exchange-sha1" ENABLE_GEX_NEW + "\"new\" diffie-hellman-group-exchange-sha1 method") +if(ENABLE_GEX_NEW) + target_compile_definitions(libssh2 PRIVATE LIBSSH2_DH_GEX_NEW=1) +endif() + +# Enable debugging logging by default if the user configured a debug build +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(DEBUG_LOGGING_DEFAULT ON) +else() + set(DEBUG_LOGGING_DEFAULT OFF) +endif() +option(ENABLE_DEBUG_LOGGING "log execution with debug trace" + ${DEBUG_LOGGING_DEFAULT}) +add_feature_info(Logging ENABLE_DEBUG_LOGGING + "Logging of execution with debug trace") +if(ENABLE_DEBUG_LOGGING) + target_compile_definitions(libssh2 PRIVATE LIBSSH2DEBUG) +endif() + +## Platform checks +check_include_files(unistd.h HAVE_UNISTD_H) +check_include_files(inttypes.h HAVE_INTTYPES_H) +check_include_files(stdlib.h HAVE_STDLIB_H) +check_include_files(sys/select.h HAVE_SYS_SELECT_H) + +check_include_files(sys/uio.h HAVE_SYS_UIO_H) +check_include_files(sys/socket.h HAVE_SYS_SOCKET_H) +check_include_files(sys/ioctl.h HAVE_SYS_IOCTL_H) +check_include_files(sys/time.h HAVE_SYS_TIME_H) +check_include_files(sys/un.h HAVE_SYS_UN_H) +check_include_files(windows.h HAVE_WINDOWS_H) +check_include_files(ws2tcpip.h HAVE_WS2TCPIP_H) +check_include_files(winsock2.h HAVE_WINSOCK2_H) + +check_type_size("long long" LONGLONG) + +if(HAVE_SYS_TIME_H) + check_symbol_exists(gettimeofday sys/time.h HAVE_GETTIMEOFDAY) +else() + check_function_exists(gettimeofday HAVE_GETTIMEOFDAY) +endif() +if(HAVE_STDLIB_H) + check_symbol_exists(strtoll stdlib.h HAVE_STRTOLL) +else() + check_function_exists(strtoll HAVE_STRTOLL) +endif() +if (NOT HAVE_STRTOLL) + # Try _strtoi64 if strtoll isn't available + check_symbol_exists(_strtoi64 stdlib.h HAVE_STRTOI64) +endif() +check_symbol_exists(snprintf stdio.h HAVE_SNPRINTF) + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR + ${CMAKE_SYSTEM_NAME} STREQUAL "Interix") + # poll() does not work on these platforms + # + # Interix: "does provide poll(), but the implementing developer must + # have been in a bad mood, because poll() only works on the /proc + # filesystem here" + # + # Mac OS X's poll has funny behaviors, like: + # not being able to do poll on no fildescriptors (10.3?) + # not being able to poll on some files (like anything in /dev) + # not having reliable timeout support + # inconsistent return of POLLHUP where other implementations give POLLIN + message("poll use is disabled on this platform") +else() + check_function_exists(poll HAVE_POLL) +endif() + +append_needed_socket_libraries(LIBRARIES) + +# Non-blocking socket support tests. Must be after after library tests to +# link correctly +set(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) +set(CMAKE_REQUIRED_LIBRARIES ${LIBRARIES}) +check_nonblocking_socket_support() +set(CMAKE_REQUIRED_LIBRARIES ${SAVE_CMAKE_REQUIRED_LIBRARIES}) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/libssh2_config_cmake.h.in + ${CMAKE_CURRENT_BINARY_DIR}/libssh2_config.h) +# to find generated header +target_include_directories(libssh2 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + +# Check for the OS. +# Daniel's note: this should not be necessary and we need to work to +# get this removed. +if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + target_compile_definitions(libssh2 PRIVATE LIBSSH2_WIN32) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + target_compile_definitions(libssh2 PRIVATE LIBSSH2_DARWIN) +endif() + +if(CMAKE_VERSION VERSION_LESS "2.8.12") + # Fall back to over-linking dependencies + target_link_libraries(libssh2 ${LIBRARIES}) +else() + target_link_libraries(libssh2 PRIVATE ${LIBRARIES}) +endif() + +## Installation + +install(FILES + ${PROJECT_SOURCE_DIR}/include/libssh2.h + ${PROJECT_SOURCE_DIR}/include/libssh2_publickey.h + ${PROJECT_SOURCE_DIR}/include/libssh2_sftp.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +install(TARGETS libssh2 + EXPORT Libssh2Config + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +if(BUILD_SHARED_LIBS) + list(APPEND _RUNTIME_DEPENDENCIES $) +endif() + +set(RUNTIME_DEPENDENCIES ${_RUNTIME_DEPENDENCIES} CACHE INTERNAL + "Files that must be in the same directory as the executables at runtime.") + +# Package config + +## During package installation, install Libssh2Config.cmake +install(EXPORT Libssh2Config + NAMESPACE Libssh2:: + DESTINATION lib/cmake/libssh2) + +## During build, register directly from build tree +# create Libssh2Config.cmake +export(TARGETS libssh2 NAMESPACE Libssh2:: FILE Libssh2Config.cmake) +export(PACKAGE Libssh2) # register it + +## Export a .pc file for client projects not using CMaek +if(PC_REQUIRES_PRIVATE) + string(REPLACE ";" "," PC_REQUIRES_PRIVATE "${PC_REQUIRES_PRIVATE}") +endif() +if(PC_LIBS) + string(REPLACE ";" " " PC_LIBS "${PC_LIBS}") +endif() +configure_file(libssh2.pc.in libssh2.pc @ONLY) +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/libssh2.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + +## Versioning + +set_target_properties(libssh2 PROPERTIES + SOVERSION 1 + VERSION 1.0.1) + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/Libssh2ConfigVersion.cmake + VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}" + COMPATIBILITY SameMajorVersion) +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/Libssh2ConfigVersion.cmake + DESTINATION lib/cmake/libssh2) diff --git a/libssh2/src/Makefile.am b/libssh2/src/Makefile.am new file mode 100644 index 000000000..c14dc7cb3 --- /dev/null +++ b/libssh2/src/Makefile.am @@ -0,0 +1,68 @@ +# $Id: Makefile.am,v 1.21 2009/05/07 17:21:56 bagder Exp $ +AUTOMAKE_OPTIONS = foreign nostdinc + +# Get the CRYPTO_CSOURCES and CRYPTO_HHEADERS defines +if OPENSSL +include ../Makefile.OpenSSL.inc +endif +if LIBGCRYPT +include ../Makefile.libgcrypt.inc +endif +if WINCNG +include ../Makefile.WinCNG.inc +endif +if OS400QC3 +include ../Makefile.os400qc3.inc +endif +if MBEDTLS +include ../Makefile.mbedTLS.inc +endif + +# Makefile.inc provides the CSOURCES and HHEADERS defines +include ../Makefile.inc + +libssh2_la_SOURCES = $(CSOURCES) $(HHEADERS) + +EXTRA_DIST = libssh2_config.h.in libssh2_config_cmake.h.in libssh2.pc.in +EXTRA_DIST += CMakeLists.txt NMakefile + +lib_LTLIBRARIES = libssh2.la + +# srcdir/include for the shipped headers +# builddir/src for the generated config header when building out of the source +# tree +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/src + +VERSION=-version-info 1:1:0 + +# This flag accepts an argument of the form current[:revision[:age]]. So, +# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to +# 1. +# +# If either revision or age are omitted, they default to 0. Also note that age +# must be less than or equal to the current interface number. +# +# Here are a set of rules to help you update your library version information: +# +# 1.Start with version information of 0:0:0 for each libtool library. +# +# 2.Update the version information only immediately before a public release of +# your software. More frequent updates are unnecessary, and only guarantee +# that the current interface number gets larger faster. +# +# 3.If the library source code has changed at all since the last update, then +# increment revision (c:r+1:a) +# +# 4.If any interfaces have been added, removed, or changed since the last +# update, increment current, and set revision to 0. (c+1:r=0:a) +# +# 5.If any interfaces have been added since the last public release, then +# increment age. (c:r:a+1) +# +# 6.If any interfaces have been removed since the last public release, then +# set age to 0. (c:r:a=0) +# + +libssh2_la_LDFLAGS = $(VERSION) -no-undefined \ + -export-symbols-regex '^libssh2_.*' \ + $(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ) diff --git a/libssh2/src/Makefile.in b/libssh2/src/Makefile.in new file mode 100644 index 000000000..9e59967ee --- /dev/null +++ b/libssh2/src/Makefile.in @@ -0,0 +1,804 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = libssh2_config.h \ + $(top_builddir)/example/libssh2_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libssh2_la_LIBADD = +am__libssh2_la_SOURCES_DIST = channel.c comp.c crypt.c hostkey.c kex.c \ + mac.c misc.c packet.c publickey.c scp.c session.c sftp.c \ + userauth.c transport.c version.c knownhost.c agent.c \ + libgcrypt.c mbedtls.c openssl.c os400qc3.c wincng.c pem.c \ + keepalive.c global.c libssh2_priv.h libgcrypt.h mbedtls.h \ + openssl.h os400qc3.h wincng.h transport.h channel.h comp.h \ + mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h +@LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_FALSE@@OS400QC3_FALSE@@WINCNG_TRUE@am__objects_1 = wincng.lo +@LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_FALSE@@OS400QC3_TRUE@am__objects_1 = os400qc3.lo +@LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_TRUE@am__objects_1 = \ +@LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_TRUE@ openssl.lo +@LIBGCRYPT_FALSE@@MBEDTLS_TRUE@am__objects_1 = mbedtls.lo +@LIBGCRYPT_TRUE@am__objects_1 = libgcrypt.lo +am__objects_2 = channel.lo comp.lo crypt.lo hostkey.lo kex.lo mac.lo \ + misc.lo packet.lo publickey.lo scp.lo session.lo sftp.lo \ + userauth.lo transport.lo version.lo knownhost.lo agent.lo \ + $(am__objects_1) pem.lo keepalive.lo global.lo +am__objects_3 = +am__objects_4 = $(am__objects_3) +am_libssh2_la_OBJECTS = $(am__objects_2) $(am__objects_4) +libssh2_la_OBJECTS = $(am_libssh2_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libssh2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libssh2_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libssh2_la_SOURCES) +DIST_SOURCES = $(am__libssh2_la_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)libssh2_config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/../Makefile.OpenSSL.inc \ + $(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.inc \ + $(srcdir)/../Makefile.libgcrypt.inc \ + $(srcdir)/../Makefile.mbedTLS.inc \ + $(srcdir)/../Makefile.os400qc3.inc $(srcdir)/Makefile.in \ + $(srcdir)/libssh2_config.h.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@ +HAVE_LIBCRYPT32 = @HAVE_LIBCRYPT32@ +HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@ +HAVE_LIBMBEDTLS = @HAVE_LIBMBEDTLS@ +HAVE_LIBSSL = @HAVE_LIBSSL@ +HAVE_LIBZ = @HAVE_LIBZ@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBBCRYPT = @LIBBCRYPT@ +LIBBCRYPT_PREFIX = @LIBBCRYPT_PREFIX@ +LIBCRYPT32 = @LIBCRYPT32@ +LIBCRYPT32_PREFIX = @LIBCRYPT32_PREFIX@ +LIBGCRYPT = @LIBGCRYPT@ +LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@ +LIBMBEDTLS = @LIBMBEDTLS@ +LIBMBEDTLS_PREFIX = @LIBMBEDTLS_PREFIX@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSREQUIRED = @LIBSREQUIRED@ +LIBSSH2VER = @LIBSSH2VER@ +LIBSSL = @LIBSSL@ +LIBSSL_PREFIX = @LIBSSL_PREFIX@ +LIBTOOL = @LIBTOOL@ +LIBZ = @LIBZ@ +LIBZ_PREFIX = @LIBZ_PREFIX@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBBCRYPT = @LTLIBBCRYPT@ +LTLIBCRYPT32 = @LTLIBCRYPT32@ +LTLIBGCRYPT = @LTLIBGCRYPT@ +LTLIBMBEDTLS = @LTLIBMBEDTLS@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBSSL = @LTLIBSSL@ +LTLIBZ = @LTLIBZ@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SSHD = @SSHD@ +STRIP = @STRIP@ +VERSION = -version-info 1:1:0 +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# $Id: Makefile.am,v 1.21 2009/05/07 17:21:56 bagder Exp $ +AUTOMAKE_OPTIONS = foreign nostdinc +@LIBGCRYPT_TRUE@CRYPTO_CSOURCES = libgcrypt.c +@MBEDTLS_TRUE@CRYPTO_CSOURCES = mbedtls.c +@OPENSSL_TRUE@CRYPTO_CSOURCES = openssl.c +@OS400QC3_TRUE@CRYPTO_CSOURCES = os400qc3.c +@WINCNG_TRUE@CRYPTO_CSOURCES = wincng.c +@LIBGCRYPT_TRUE@CRYPTO_HHEADERS = libgcrypt.h +@MBEDTLS_TRUE@CRYPTO_HHEADERS = mbedtls.h +@OPENSSL_TRUE@CRYPTO_HHEADERS = openssl.h +@OS400QC3_TRUE@CRYPTO_HHEADERS = os400qc3.h +@WINCNG_TRUE@CRYPTO_HHEADERS = wincng.h +CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \ + packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \ + version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c + +HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \ + mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h + + +# Get the CRYPTO_CSOURCES and CRYPTO_HHEADERS defines + +# Makefile.inc provides the CSOURCES and HHEADERS defines +libssh2_la_SOURCES = $(CSOURCES) $(HHEADERS) +EXTRA_DIST = libssh2_config.h.in libssh2_config_cmake.h.in \ + libssh2.pc.in CMakeLists.txt NMakefile +lib_LTLIBRARIES = libssh2.la + +# srcdir/include for the shipped headers +# builddir/src for the generated config header when building out of the source +# tree +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/src + +# This flag accepts an argument of the form current[:revision[:age]]. So, +# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to +# 1. +# +# If either revision or age are omitted, they default to 0. Also note that age +# must be less than or equal to the current interface number. +# +# Here are a set of rules to help you update your library version information: +# +# 1.Start with version information of 0:0:0 for each libtool library. +# +# 2.Update the version information only immediately before a public release of +# your software. More frequent updates are unnecessary, and only guarantee +# that the current interface number gets larger faster. +# +# 3.If the library source code has changed at all since the last update, then +# increment revision (c:r+1:a) +# +# 4.If any interfaces have been added, removed, or changed since the last +# update, increment current, and set revision to 0. (c+1:r=0:a) +# +# 5.If any interfaces have been added since the last public release, then +# increment age. (c:r:a+1) +# +# 6.If any interfaces have been removed since the last public release, then +# set age to 0. (c:r:a=0) +# +libssh2_la_LDFLAGS = $(VERSION) -no-undefined \ + -export-symbols-regex '^libssh2_.*' \ + $(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ) + +all: libssh2_config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../Makefile.OpenSSL.inc $(srcdir)/../Makefile.libgcrypt.inc $(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.os400qc3.inc $(srcdir)/../Makefile.mbedTLS.inc $(srcdir)/../Makefile.inc $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; +$(srcdir)/../Makefile.OpenSSL.inc $(srcdir)/../Makefile.libgcrypt.inc $(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.os400qc3.inc $(srcdir)/../Makefile.mbedTLS.inc $(srcdir)/../Makefile.inc $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +libssh2_config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/libssh2_config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status src/libssh2_config.h +$(srcdir)/libssh2_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f libssh2_config.h stamp-h1 + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libssh2.la: $(libssh2_la_OBJECTS) $(libssh2_la_DEPENDENCIES) $(EXTRA_libssh2_la_DEPENDENCIES) + $(AM_V_CCLD)$(libssh2_la_LINK) -rpath $(libdir) $(libssh2_la_OBJECTS) $(libssh2_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agent.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/global.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hostkey.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keepalive.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kex.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/knownhost.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbedtls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os400qc3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/publickey.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sftp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transport.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/userauth.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wincng.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) libssh2_config.h +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: all install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libssh2/src/NMakefile b/libssh2/src/NMakefile new file mode 100644 index 000000000..0c4853f1d --- /dev/null +++ b/libssh2/src/NMakefile @@ -0,0 +1,30 @@ +!include "win32/config.mk" + +!include "win32/objects.mk" + +CFLAGS=$(CFLAGS) + +AR = lib +ARFLAGS = -nologo /LTCG + +RESOURCE=$(INTDIR)\libssh2.res +DLL=libssh2$(SUFFIX).dll +STATICLIB=$(INTDIR)\libssh2.lib + +!if "$(BUILD_STATIC_LIB)" == "" +all: $(DLL) +!else +all: $(STATICLIB) +!endif + +$(DLL): $(OBJECTS) $(RESOURCE) + $(CC) -o $(DLL) $(DLLFLAGS) $(OBJECTS) $(RESOURCE) $(LIBS) + +$(STATICLIB): $(OBJECTS) + $(AR) $(ARFLAGS) -out:$@ $(OBJECTS) + +$(RESOURCE): win32\libssh2.rc + $(RC) $(RCFLAGS) /Fo"$@" $? + +!include "win32/rules.mk" + diff --git a/libssh2/src/agent.c b/libssh2/src/agent.c new file mode 100644 index 000000000..c2ba422b6 --- /dev/null +++ b/libssh2/src/agent.c @@ -0,0 +1,811 @@ +/* + * Copyright (c) 2009 by Daiki Ueno + * Copyright (C) 2010-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" +#include +#ifdef HAVE_SYS_UN_H +#include +#else +/* Use the existence of sys/un.h as a test if Unix domain socket is + supported. winsock*.h define PF_UNIX/AF_UNIX but do not actually + support them. */ +#undef PF_UNIX +#endif +#include "userauth.h" +#include "session.h" + +/* Requests from client to agent for protocol 1 key operations */ +#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 +#define SSH_AGENTC_RSA_CHALLENGE 3 +#define SSH_AGENTC_ADD_RSA_IDENTITY 7 +#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 +#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 +#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 + +/* Requests from client to agent for protocol 2 key operations */ +#define SSH2_AGENTC_REQUEST_IDENTITIES 11 +#define SSH2_AGENTC_SIGN_REQUEST 13 +#define SSH2_AGENTC_ADD_IDENTITY 17 +#define SSH2_AGENTC_REMOVE_IDENTITY 18 +#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 +#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25 + +/* Key-type independent requests from client to agent */ +#define SSH_AGENTC_ADD_SMARTCARD_KEY 20 +#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 +#define SSH_AGENTC_LOCK 22 +#define SSH_AGENTC_UNLOCK 23 +#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 + +/* Generic replies from agent to client */ +#define SSH_AGENT_FAILURE 5 +#define SSH_AGENT_SUCCESS 6 + +/* Replies from agent to client for protocol 1 key operations */ +#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 +#define SSH_AGENT_RSA_RESPONSE 4 + +/* Replies from agent to client for protocol 2 key operations */ +#define SSH2_AGENT_IDENTITIES_ANSWER 12 +#define SSH2_AGENT_SIGN_RESPONSE 14 + +/* Key constraint identifiers */ +#define SSH_AGENT_CONSTRAIN_LIFETIME 1 +#define SSH_AGENT_CONSTRAIN_CONFIRM 2 + +/* non-blocking mode on agent connection is not yet implemented, but + for future use. */ +typedef enum { + agent_NB_state_init = 0, + agent_NB_state_request_created, + agent_NB_state_request_length_sent, + agent_NB_state_request_sent, + agent_NB_state_response_length_received, + agent_NB_state_response_received +} agent_nonblocking_states; + +typedef struct agent_transaction_ctx { + unsigned char *request; + size_t request_len; + unsigned char *response; + size_t response_len; + agent_nonblocking_states state; +} *agent_transaction_ctx_t; + +typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent); +typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent, + agent_transaction_ctx_t transctx); +typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent); + +struct agent_publickey { + struct list_node node; + + /* this is the struct we expose externally */ + struct libssh2_agent_publickey external; +}; + +struct agent_ops { + agent_connect_func connect; + agent_transact_func transact; + agent_disconnect_func disconnect; +}; + +struct _LIBSSH2_AGENT +{ + LIBSSH2_SESSION *session; /* the session this "belongs to" */ + + libssh2_socket_t fd; + + struct agent_ops *ops; + + struct agent_transaction_ctx transctx; + struct agent_publickey *identity; + struct list_head head; /* list of public keys */ +}; + +#ifdef PF_UNIX +static int +agent_connect_unix(LIBSSH2_AGENT *agent) +{ + const char *path; + struct sockaddr_un s_un; + + path = getenv("SSH_AUTH_SOCK"); + if (!path) + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, + "no auth sock variable"); + + agent->fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (agent->fd < 0) + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_SOCKET, + "failed creating socket"); + + s_un.sun_family = AF_UNIX; + strncpy (s_un.sun_path, path, sizeof s_un.sun_path); + s_un.sun_path[sizeof(s_un.sun_path)-1]=0; /* make sure there's a trailing + zero */ + if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) { + close (agent->fd); + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed connecting with agent"); + } + + return LIBSSH2_ERROR_NONE; +} + +static int +agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx) +{ + unsigned char buf[4]; + int rc; + + /* Send the length of the request */ + if (transctx->state == agent_NB_state_request_created) { + _libssh2_htonu32(buf, transctx->request_len); + rc = LIBSSH2_SEND_FD(agent->session, agent->fd, buf, sizeof buf, 0); + if (rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + else if (rc < 0) + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, + "agent send failed"); + transctx->state = agent_NB_state_request_length_sent; + } + + /* Send the request body */ + if (transctx->state == agent_NB_state_request_length_sent) { + rc = LIBSSH2_SEND_FD(agent->session, agent->fd, transctx->request, + transctx->request_len, 0); + if (rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + else if (rc < 0) + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, + "agent send failed"); + transctx->state = agent_NB_state_request_sent; + } + + /* Receive the length of a response */ + if (transctx->state == agent_NB_state_request_sent) { + rc = LIBSSH2_RECV_FD(agent->session, agent->fd, buf, sizeof buf, 0); + if (rc < 0) { + if (rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV, + "agent recv failed"); + } + transctx->response_len = _libssh2_ntohu32(buf); + transctx->response = LIBSSH2_ALLOC(agent->session, + transctx->response_len); + if (!transctx->response) + return LIBSSH2_ERROR_ALLOC; + + transctx->state = agent_NB_state_response_length_received; + } + + /* Receive the response body */ + if (transctx->state == agent_NB_state_response_length_received) { + rc = LIBSSH2_RECV_FD(agent->session, agent->fd, transctx->response, + transctx->response_len, 0); + if (rc < 0) { + if (rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, + "agent recv failed"); + } + transctx->state = agent_NB_state_response_received; + } + + return 0; +} + +static int +agent_disconnect_unix(LIBSSH2_AGENT *agent) +{ + int ret; + ret = close(agent->fd); + if(ret != -1) + agent->fd = LIBSSH2_INVALID_SOCKET; + else + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT, + "failed closing the agent socket"); + return LIBSSH2_ERROR_NONE; +} + +struct agent_ops agent_ops_unix = { + agent_connect_unix, + agent_transact_unix, + agent_disconnect_unix +}; +#endif /* PF_UNIX */ + +#ifdef WIN32 +/* Code to talk to Pageant was taken from PuTTY. + * + * Portions copyright Robert de Bath, Joris van Rantwijk, Delian + * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas + * Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, + * Markus Kuhn, Colin Watson, and CORE SDI S.A. + */ +#define PAGEANT_COPYDATA_ID 0x804e50ba /* random goop */ +#define PAGEANT_MAX_MSGLEN 8192 + +static int +agent_connect_pageant(LIBSSH2_AGENT *agent) +{ + HWND hwnd; + hwnd = FindWindow("Pageant", "Pageant"); + if (!hwnd) + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed connecting agent"); + agent->fd = 0; /* Mark as the connection has been established */ + return LIBSSH2_ERROR_NONE; +} + +static int +agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx) +{ + HWND hwnd; + char mapname[23]; + HANDLE filemap; + unsigned char *p; + unsigned char *p2; + int id; + COPYDATASTRUCT cds; + + if (!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN) + return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL, + "illegal input"); + + hwnd = FindWindow("Pageant", "Pageant"); + if (!hwnd) + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "found no pageant"); + + sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId()); + filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, + 0, PAGEANT_MAX_MSGLEN, mapname); + + if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed setting up pageant filemap"); + + p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0); + if (p == NULL || p2 == NULL) { + CloseHandle(filemap); + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed to open pageant filemap for writing"); + } + + _libssh2_store_str(&p2, (const char *)transctx->request, + transctx->request_len); + + cds.dwData = PAGEANT_COPYDATA_ID; + cds.cbData = 1 + strlen(mapname); + cds.lpData = mapname; + + id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds); + if (id > 0) { + transctx->response_len = _libssh2_ntohu32(p); + if (transctx->response_len > PAGEANT_MAX_MSGLEN) { + UnmapViewOfFile(p); + CloseHandle(filemap); + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "agent setup fail"); + } + transctx->response = LIBSSH2_ALLOC(agent->session, + transctx->response_len); + if (!transctx->response) { + UnmapViewOfFile(p); + CloseHandle(filemap); + return _libssh2_error(agent->session, LIBSSH2_ERROR_ALLOC, + "agent malloc"); + } + memcpy(transctx->response, p + 4, transctx->response_len); + } + + UnmapViewOfFile(p); + CloseHandle(filemap); + return 0; +} + +static int +agent_disconnect_pageant(LIBSSH2_AGENT *agent) +{ + agent->fd = LIBSSH2_INVALID_SOCKET; + return 0; +} + +struct agent_ops agent_ops_pageant = { + agent_connect_pageant, + agent_transact_pageant, + agent_disconnect_pageant +}; +#endif /* WIN32 */ + +static struct { + const char *name; + struct agent_ops *ops; +} supported_backends[] = { +#ifdef WIN32 + {"Pageant", &agent_ops_pageant}, +#endif /* WIN32 */ +#ifdef PF_UNIX + {"Unix", &agent_ops_unix}, +#endif /* PF_UNIX */ + {NULL, NULL} +}; + +static int +agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, + const unsigned char *data, size_t data_len, void **abstract) +{ + LIBSSH2_AGENT *agent = (LIBSSH2_AGENT *) (*abstract); + agent_transaction_ctx_t transctx = &agent->transctx; + struct agent_publickey *identity = agent->identity; + ssize_t len = 1 + 4 + identity->external.blob_len + 4 + data_len + 4; + ssize_t method_len; + unsigned char *s; + int rc; + + /* Create a request to sign the data */ + if (transctx->state == agent_NB_state_init) { + s = transctx->request = LIBSSH2_ALLOC(session, len); + if (!transctx->request) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "out of memory"); + + *s++ = SSH2_AGENTC_SIGN_REQUEST; + /* key blob */ + _libssh2_store_str(&s, (const char *)identity->external.blob, + identity->external.blob_len); + /* data */ + _libssh2_store_str(&s, (const char *)data, data_len); + + /* flags */ + _libssh2_store_u32(&s, 0); + + transctx->request_len = s - transctx->request; + transctx->state = agent_NB_state_request_created; + } + + /* Make sure to be re-called as a result of EAGAIN. */ + if (*transctx->request != SSH2_AGENTC_SIGN_REQUEST) + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "illegal request"); + + if (!agent->ops) + /* if no agent has been connected, bail out */ + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "agent not connected"); + + rc = agent->ops->transact(agent, transctx); + if (rc) { + goto error; + } + LIBSSH2_FREE(session, transctx->request); + transctx->request = NULL; + + len = transctx->response_len; + s = transctx->response; + len--; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + if (*s != SSH2_AGENT_SIGN_RESPONSE) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s++; + + /* Skip the entire length of the signature */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s += 4; + + /* Skip signing method */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + method_len = _libssh2_ntohu32(s); + s += 4; + len -= method_len; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s += method_len; + + /* Read the signature */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + *sig_len = _libssh2_ntohu32(s); + s += 4; + len -= *sig_len; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + + *sig = LIBSSH2_ALLOC(session, *sig_len); + if (!*sig) { + rc = LIBSSH2_ERROR_ALLOC; + goto error; + } + memcpy(*sig, s, *sig_len); + + error: + LIBSSH2_FREE(session, transctx->request); + transctx->request = NULL; + + LIBSSH2_FREE(session, transctx->response); + transctx->response = NULL; + + return _libssh2_error(session, rc, "agent sign failure"); +} + +static int +agent_list_identities(LIBSSH2_AGENT *agent) +{ + agent_transaction_ctx_t transctx = &agent->transctx; + ssize_t len, num_identities; + unsigned char *s; + int rc; + unsigned char c = SSH2_AGENTC_REQUEST_IDENTITIES; + + /* Create a request to list identities */ + if (transctx->state == agent_NB_state_init) { + transctx->request = &c; + transctx->request_len = 1; + transctx->state = agent_NB_state_request_created; + } + + /* Make sure to be re-called as a result of EAGAIN. */ + if (*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES) + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, + "illegal agent request"); + + if (!agent->ops) + /* if no agent has been connected, bail out */ + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, + "agent not connected"); + + rc = agent->ops->transact(agent, transctx); + if (rc) { + goto error; + } + transctx->request = NULL; + + len = transctx->response_len; + s = transctx->response; + len--; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + if (*s != SSH2_AGENT_IDENTITIES_ANSWER) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s++; + + /* Read the length of identities */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + num_identities = _libssh2_ntohu32(s); + s += 4; + + while (num_identities--) { + struct agent_publickey *identity; + ssize_t comment_len; + + /* Read the length of the blob */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + identity = LIBSSH2_ALLOC(agent->session, sizeof *identity); + if (!identity) { + rc = LIBSSH2_ERROR_ALLOC; + goto error; + } + identity->external.blob_len = _libssh2_ntohu32(s); + s += 4; + + /* Read the blob */ + len -= identity->external.blob_len; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + LIBSSH2_FREE(agent->session, identity); + goto error; + } + + identity->external.blob = LIBSSH2_ALLOC(agent->session, + identity->external.blob_len); + if (!identity->external.blob) { + rc = LIBSSH2_ERROR_ALLOC; + LIBSSH2_FREE(agent->session, identity); + goto error; + } + memcpy(identity->external.blob, s, identity->external.blob_len); + s += identity->external.blob_len; + + /* Read the length of the comment */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + LIBSSH2_FREE(agent->session, identity->external.blob); + LIBSSH2_FREE(agent->session, identity); + goto error; + } + comment_len = _libssh2_ntohu32(s); + s += 4; + + /* Read the comment */ + len -= comment_len; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + LIBSSH2_FREE(agent->session, identity->external.blob); + LIBSSH2_FREE(agent->session, identity); + goto error; + } + + identity->external.comment = LIBSSH2_ALLOC(agent->session, + comment_len + 1); + if (!identity->external.comment) { + rc = LIBSSH2_ERROR_ALLOC; + LIBSSH2_FREE(agent->session, identity->external.blob); + LIBSSH2_FREE(agent->session, identity); + goto error; + } + identity->external.comment[comment_len] = '\0'; + memcpy(identity->external.comment, s, comment_len); + s += comment_len; + + _libssh2_list_add(&agent->head, &identity->node); + } + error: + LIBSSH2_FREE(agent->session, transctx->response); + transctx->response = NULL; + + return _libssh2_error(agent->session, rc, + "agent list id failed"); +} + +static void +agent_free_identities(LIBSSH2_AGENT *agent) { + struct agent_publickey *node; + struct agent_publickey *next; + + for (node = _libssh2_list_first(&agent->head); node; node = next) { + next = _libssh2_list_next(&node->node); + LIBSSH2_FREE(agent->session, node->external.blob); + LIBSSH2_FREE(agent->session, node->external.comment); + LIBSSH2_FREE(agent->session, node); + } + _libssh2_list_init(&agent->head); +} + +#define AGENT_PUBLICKEY_MAGIC 0x3bdefed2 +/* + * agent_publickey_to_external() + * + * Copies data from the internal to the external representation struct. + * + */ +static struct libssh2_agent_publickey * +agent_publickey_to_external(struct agent_publickey *node) +{ + struct libssh2_agent_publickey *ext = &node->external; + + ext->magic = AGENT_PUBLICKEY_MAGIC; + ext->node = node; + + return ext; +} + +/* + * libssh2_agent_init + * + * Init an ssh-agent handle. Returns the pointer to the handle. + * + */ +LIBSSH2_API LIBSSH2_AGENT * +libssh2_agent_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_AGENT *agent; + + agent = LIBSSH2_CALLOC(session, sizeof *agent); + if (!agent) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate space for agent connection"); + return NULL; + } + agent->fd = LIBSSH2_INVALID_SOCKET; + agent->session = session; + _libssh2_list_init(&agent->head); + + return agent; +} + +/* + * libssh2_agent_connect() + * + * Connect to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_connect(LIBSSH2_AGENT *agent) +{ + int i, rc = -1; + for (i = 0; supported_backends[i].name; i++) { + agent->ops = supported_backends[i].ops; + rc = (agent->ops->connect)(agent); + if (!rc) + return 0; + } + return rc; +} + +/* + * libssh2_agent_list_identities() + * + * Request ssh-agent to list identities. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_list_identities(LIBSSH2_AGENT *agent) +{ + memset(&agent->transctx, 0, sizeof agent->transctx); + /* Abondon the last fetched identities */ + agent_free_identities(agent); + return agent_list_identities(agent); +} + +/* + * libssh2_agent_get_identity() + * + * Traverse the internal list of public keys. Pass NULL to 'prev' to get + * the first one. Or pass a pointer to the previously returned one to get the + * next. + * + * Returns: + * 0 if a fine public key was stored in 'store' + * 1 if end of public keys + * [negative] on errors + */ +LIBSSH2_API int +libssh2_agent_get_identity(LIBSSH2_AGENT *agent, + struct libssh2_agent_publickey **ext, + struct libssh2_agent_publickey *oprev) +{ + struct agent_publickey *node; + if (oprev && oprev->node) { + /* we have a starting point */ + struct agent_publickey *prev = oprev->node; + + /* get the next node in the list */ + node = _libssh2_list_next(&prev->node); + } + else + node = _libssh2_list_first(&agent->head); + + if (!node) + /* no (more) node */ + return 1; + + *ext = agent_publickey_to_external(node); + + return 0; +} + +/* + * libssh2_agent_userauth() + * + * Do publickey user authentication with the help of ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_userauth(LIBSSH2_AGENT *agent, + const char *username, + struct libssh2_agent_publickey *identity) +{ + void *abstract = agent; + int rc; + + if (agent->session->userauth_pblc_state == libssh2_NB_state_idle) { + memset(&agent->transctx, 0, sizeof agent->transctx); + agent->identity = identity->node; + } + + BLOCK_ADJUST(rc, agent->session, + _libssh2_userauth_publickey(agent->session, username, + strlen(username), + identity->blob, + identity->blob_len, + agent_sign, + &abstract)); + return rc; +} + +/* + * libssh2_agent_disconnect() + * + * Close a connection to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_disconnect(LIBSSH2_AGENT *agent) +{ + if (agent->ops && agent->fd != LIBSSH2_INVALID_SOCKET) + return agent->ops->disconnect(agent); + return 0; +} + +/* + * libssh2_agent_free() + * + * Free an ssh-agent handle. This function also frees the internal + * collection of public keys. + */ +LIBSSH2_API void +libssh2_agent_free(LIBSSH2_AGENT *agent) { + /* Allow connection freeing when the socket has lost its connection */ + if (agent->fd != LIBSSH2_INVALID_SOCKET) { + libssh2_agent_disconnect(agent); + } + agent_free_identities(agent); + LIBSSH2_FREE(agent->session, agent); +} diff --git a/libssh2/src/channel.c b/libssh2/src/channel.c new file mode 100644 index 000000000..538a0ab0d --- /dev/null +++ b/libssh2/src/channel.c @@ -0,0 +1,2621 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2005 Mikhail Gusarov + * Copyright (c) 2008-2014 by Daniel Stenberg + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifdef HAVE_INTTYPES_H +#include +#endif +#include + +#include "channel.h" +#include "transport.h" +#include "packet.h" +#include "session.h" + +/* + * _libssh2_channel_nextid + * + * Determine the next channel ID we can use at our end + */ +uint32_t +_libssh2_channel_nextid(LIBSSH2_SESSION * session) +{ + uint32_t id = session->next_channel; + LIBSSH2_CHANNEL *channel; + + channel = _libssh2_list_first(&session->channels); + + while (channel) { + if (channel->local.id > id) { + id = channel->local.id; + } + channel = _libssh2_list_next(&channel->node); + } + + /* This is a shortcut to avoid waiting for close packets on channels we've + * forgotten about, This *could* be a problem if we request and close 4 + * billion or so channels in too rapid succession for the remote end to + * respond, but the worst case scenario is that some data meant for + * another channel Gets picked up by the new one.... Pretty unlikely all + * told... + */ + session->next_channel = id + 1; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, "Allocated new channel ID#%lu", + id); + return id; +} + +/* + * _libssh2_channel_locate + * + * Locate a channel pointer by number + */ +LIBSSH2_CHANNEL * +_libssh2_channel_locate(LIBSSH2_SESSION *session, uint32_t channel_id) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_LISTENER *l; + + for(channel = _libssh2_list_first(&session->channels); + channel; + channel = _libssh2_list_next(&channel->node)) { + if (channel->local.id == channel_id) + return channel; + } + + /* We didn't find the channel in the session, let's then check its + listeners since each listener may have its own set of pending channels + */ + for(l = _libssh2_list_first(&session->listeners); l; + l = _libssh2_list_next(&l->node)) { + for(channel = _libssh2_list_first(&l->queue); + channel; + channel = _libssh2_list_next(&channel->node)) { + if (channel->local.id == channel_id) + return channel; + } + } + + return NULL; +} + +/* + * _libssh2_channel_open + * + * Establish a generic session channel + */ +LIBSSH2_CHANNEL * +_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type, + uint32_t channel_type_len, + uint32_t window_size, + uint32_t packet_size, + const unsigned char *message, + size_t message_len) +{ + static const unsigned char reply_codes[3] = { + SSH_MSG_CHANNEL_OPEN_CONFIRMATION, + SSH_MSG_CHANNEL_OPEN_FAILURE, + 0 + }; + unsigned char *s; + int rc; + + if (session->open_state == libssh2_NB_state_idle) { + session->open_channel = NULL; + session->open_packet = NULL; + session->open_data = NULL; + /* 17 = packet_type(1) + channel_type_len(4) + sender_channel(4) + + * window_size(4) + packet_size(4) */ + session->open_packet_len = channel_type_len + 17; + session->open_local_channel = _libssh2_channel_nextid(session); + + /* Zero the whole thing out */ + memset(&session->open_packet_requirev_state, 0, + sizeof(session->open_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Opening Channel - win %d pack %d", window_size, + packet_size); + session->open_channel = + LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if (!session->open_channel) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate space for channel data"); + return NULL; + } + session->open_channel->channel_type_len = channel_type_len; + session->open_channel->channel_type = + LIBSSH2_ALLOC(session, channel_type_len); + if (!session->open_channel->channel_type) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating memory for channel type name"); + LIBSSH2_FREE(session, session->open_channel); + session->open_channel = NULL; + return NULL; + } + memcpy(session->open_channel->channel_type, channel_type, + channel_type_len); + + /* REMEMBER: local as in locally sourced */ + session->open_channel->local.id = session->open_local_channel; + session->open_channel->remote.window_size = window_size; + session->open_channel->remote.window_size_initial = window_size; + session->open_channel->remote.packet_size = packet_size; + session->open_channel->session = session; + + _libssh2_list_add(&session->channels, + &session->open_channel->node); + + s = session->open_packet = + LIBSSH2_ALLOC(session, session->open_packet_len); + if (!session->open_packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate temporary space for packet"); + goto channel_error; + } + *(s++) = SSH_MSG_CHANNEL_OPEN; + _libssh2_store_str(&s, channel_type, channel_type_len); + _libssh2_store_u32(&s, session->open_local_channel); + _libssh2_store_u32(&s, window_size); + _libssh2_store_u32(&s, packet_size); + + /* Do not copy the message */ + + session->open_state = libssh2_NB_state_created; + } + + if (session->open_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + session->open_packet, + session->open_packet_len, + message, message_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending channel-open request"); + return NULL; + } + else if (rc) { + _libssh2_error(session, rc, + "Unable to send channel-open request"); + goto channel_error; + } + + session->open_state = libssh2_NB_state_sent; + } + + if (session->open_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->open_data, + &session->open_data_len, 1, + session->open_packet + 5 + + channel_type_len, 4, + &session->open_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + return NULL; + } else if (rc) { + goto channel_error; + } + + if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) { + session->open_channel->remote.id = + _libssh2_ntohu32(session->open_data + 5); + session->open_channel->local.window_size = + _libssh2_ntohu32(session->open_data + 9); + session->open_channel->local.window_size_initial = + _libssh2_ntohu32(session->open_data + 9); + session->open_channel->local.packet_size = + _libssh2_ntohu32(session->open_data + 13); + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Connection Established - ID: %lu/%lu win: %lu/%lu" + " pack: %lu/%lu", + session->open_channel->local.id, + session->open_channel->remote.id, + session->open_channel->local.window_size, + session->open_channel->remote.window_size, + session->open_channel->local.packet_size, + session->open_channel->remote.packet_size); + LIBSSH2_FREE(session, session->open_packet); + session->open_packet = NULL; + LIBSSH2_FREE(session, session->open_data); + session->open_data = NULL; + + session->open_state = libssh2_NB_state_idle; + return session->open_channel; + } + + if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) { + unsigned int reason_code = _libssh2_ntohu32(session->open_data + 5); + switch (reason_code) { + case SSH_OPEN_ADMINISTRATIVELY_PROHIBITED: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (administratively prohibited)"); + break; + case SSH_OPEN_CONNECT_FAILED: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (connect failed)"); + break; + case SSH_OPEN_UNKNOWN_CHANNELTYPE: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (unknown channel type)"); + break; + case SSH_OPEN_RESOURCE_SHORTAGE: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (resource shortage)"); + break; + default: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure"); + } + } + } + + channel_error: + + if (session->open_data) { + LIBSSH2_FREE(session, session->open_data); + session->open_data = NULL; + } + if (session->open_packet) { + LIBSSH2_FREE(session, session->open_packet); + session->open_packet = NULL; + } + if (session->open_channel) { + unsigned char channel_id[4]; + LIBSSH2_FREE(session, session->open_channel->channel_type); + + _libssh2_list_remove(&session->open_channel->node); + + /* Clear out packets meant for this channel */ + _libssh2_htonu32(channel_id, session->open_channel->local.id); + while ((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, + &session->open_data, + &session->open_data_len, 1, + channel_id, 4) >= 0) + || + (_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, + &session->open_data, + &session->open_data_len, 1, + channel_id, 4) >= 0)) { + LIBSSH2_FREE(session, session->open_data); + session->open_data = NULL; + } + + LIBSSH2_FREE(session, session->open_channel); + session->open_channel = NULL; + } + + session->open_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_channel_open_ex + * + * Establish a generic session channel + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *type, + unsigned int type_len, + unsigned int window_size, unsigned int packet_size, + const char *msg, unsigned int msg_len) +{ + LIBSSH2_CHANNEL *ptr; + + if(!session) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, + _libssh2_channel_open(session, type, type_len, + window_size, packet_size, + (unsigned char *)msg, + msg_len)); + return ptr; +} + +/* + * libssh2_channel_direct_tcpip_ex + * + * Tunnel TCP/IP connect through the SSH session to direct host/port + */ +static LIBSSH2_CHANNEL * +channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host, + int port, const char *shost, int sport) +{ + LIBSSH2_CHANNEL *channel; + unsigned char *s; + + if (session->direct_state == libssh2_NB_state_idle) { + session->direct_host_len = strlen(host); + session->direct_shost_len = strlen(shost); + /* host_len(4) + port(4) + shost_len(4) + sport(4) */ + session->direct_message_len = + session->direct_host_len + session->direct_shost_len + 16; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting direct-tcpip session to from %s:%d to %s:%d", + shost, sport, host, port); + + s = session->direct_message = + LIBSSH2_ALLOC(session, session->direct_message_len); + if (!session->direct_message) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for direct-tcpip connection"); + return NULL; + } + _libssh2_store_str(&s, host, session->direct_host_len); + _libssh2_store_u32(&s, port); + _libssh2_store_str(&s, shost, session->direct_shost_len); + _libssh2_store_u32(&s, sport); + } + + channel = + _libssh2_channel_open(session, "direct-tcpip", + sizeof("direct-tcpip") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, + session->direct_message, + session->direct_message_len); + + if (!channel && + libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { + /* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state + to created to avoid re-creating the package on next invoke */ + session->direct_state = libssh2_NB_state_created; + return NULL; + } + /* by default we set (keep?) idle state... */ + session->direct_state = libssh2_NB_state_idle; + + LIBSSH2_FREE(session, session->direct_message); + session->direct_message = NULL; + + return channel; +} + +/* + * libssh2_channel_direct_tcpip_ex + * + * Tunnel TCP/IP connect through the SSH session to direct host/port + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, + int port, const char *shost, int sport) +{ + LIBSSH2_CHANNEL *ptr; + + if(!session) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, + channel_direct_tcpip(session, host, port, shost, sport)); + return ptr; +} + +/* + * channel_forward_listen + * + * Bind a port on the remote host and listen for connections + */ +static LIBSSH2_LISTENER * +channel_forward_listen(LIBSSH2_SESSION * session, const char *host, + int port, int *bound_port, int queue_maxsize) +{ + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 }; + int rc; + + if(!host) + host = "0.0.0.0"; + + if (session->fwdLstn_state == libssh2_NB_state_idle) { + session->fwdLstn_host_len = strlen(host); + /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + + port(4) */ + session->fwdLstn_packet_len = + session->fwdLstn_host_len + (sizeof("tcpip-forward") - 1) + 14; + + /* Zero the whole thing out */ + memset(&session->fwdLstn_packet_requirev_state, 0, + sizeof(session->fwdLstn_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting tcpip-forward session for %s:%d", host, + port); + + s = session->fwdLstn_packet = + LIBSSH2_ALLOC(session, session->fwdLstn_packet_len); + if (!session->fwdLstn_packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for setenv packet"); + return NULL; + } + + *(s++) = SSH_MSG_GLOBAL_REQUEST; + _libssh2_store_str(&s, "tcpip-forward", sizeof("tcpip-forward") - 1); + *(s++) = 0x01; /* want_reply */ + + _libssh2_store_str(&s, host, session->fwdLstn_host_len); + _libssh2_store_u32(&s, port); + + session->fwdLstn_state = libssh2_NB_state_created; + } + + if (session->fwdLstn_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + session->fwdLstn_packet, + session->fwdLstn_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending global-request packet for " + "forward listen request"); + return NULL; + } + else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send global-request packet for forward " + "listen request"); + LIBSSH2_FREE(session, session->fwdLstn_packet); + session->fwdLstn_packet = NULL; + session->fwdLstn_state = libssh2_NB_state_idle; + return NULL; + } + LIBSSH2_FREE(session, session->fwdLstn_packet); + session->fwdLstn_packet = NULL; + + session->fwdLstn_state = libssh2_NB_state_sent; + } + + if (session->fwdLstn_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 0, NULL, 0, + &session->fwdLstn_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + return NULL; + } else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown"); + session->fwdLstn_state = libssh2_NB_state_idle; + return NULL; + } + + if (data[0] == SSH_MSG_REQUEST_SUCCESS) { + LIBSSH2_LISTENER *listener; + + listener = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_LISTENER)); + if (!listener) + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for listener queue"); + else { + listener->host = + LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1); + if (!listener->host) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for listener queue"); + LIBSSH2_FREE(session, listener); + listener = NULL; + } + else { + listener->session = session; + memcpy(listener->host, host, session->fwdLstn_host_len); + listener->host[session->fwdLstn_host_len] = 0; + if (data_len >= 5 && !port) { + listener->port = _libssh2_ntohu32(data + 1); + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Dynamic tcpip-forward port allocated: %d", + listener->port); + } + else + listener->port = port; + + listener->queue_size = 0; + listener->queue_maxsize = queue_maxsize; + + /* append this to the parent's list of listeners */ + _libssh2_list_add(&session->listeners, &listener->node); + + if (bound_port) { + *bound_port = listener->port; + } + } + } + + LIBSSH2_FREE(session, data); + session->fwdLstn_state = libssh2_NB_state_idle; + return listener; + } + else if (data[0] == SSH_MSG_REQUEST_FAILURE) { + LIBSSH2_FREE(session, data); + _libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED, + "Unable to complete request for forward-listen"); + session->fwdLstn_state = libssh2_NB_state_idle; + return NULL; + } + } + + session->fwdLstn_state = libssh2_NB_state_idle; + + return NULL; +} + +/* + * libssh2_channel_forward_listen_ex + * + * Bind a port on the remote host and listen for connections + */ +LIBSSH2_API LIBSSH2_LISTENER * +libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, + int port, int *bound_port, int queue_maxsize) +{ + LIBSSH2_LISTENER *ptr; + + if(!session) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, + channel_forward_listen(session, host, port, bound_port, + queue_maxsize)); + return ptr; +} + +/* + * _libssh2_channel_forward_cancel + * + * Stop listening on a remote port and free the listener + * Toss out any pending (un-accept()ed) connections + * + * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error + */ +int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) +{ + LIBSSH2_SESSION *session = listener->session; + LIBSSH2_CHANNEL *queued; + unsigned char *packet, *s; + size_t host_len = strlen(listener->host); + /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + + port(4) */ + size_t packet_len = + host_len + 14 + sizeof("cancel-tcpip-forward") - 1; + int rc; + int retcode = 0; + + if (listener->chanFwdCncl_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Cancelling tcpip-forward session for %s:%d", + listener->host, listener->port); + + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for setenv packet"); + return LIBSSH2_ERROR_ALLOC; + } + + *(s++) = SSH_MSG_GLOBAL_REQUEST; + _libssh2_store_str(&s, "cancel-tcpip-forward", + sizeof("cancel-tcpip-forward") - 1); + *(s++) = 0x00; /* want_reply */ + + _libssh2_store_str(&s, listener->host, host_len); + _libssh2_store_u32(&s, listener->port); + + listener->chanFwdCncl_state = libssh2_NB_state_created; + } else { + packet = listener->chanFwdCncl_data; + } + + if (listener->chanFwdCncl_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, packet, packet_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending forward request"); + listener->chanFwdCncl_data = packet; + return rc; + } + else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send global-request packet for forward " + "listen request"); + /* set the state to something we don't check for, for the + unfortunate situation where we get an EAGAIN further down + when trying to bail out due to errors! */ + listener->chanFwdCncl_state = libssh2_NB_state_sent; + retcode = LIBSSH2_ERROR_SOCKET_SEND; + } + LIBSSH2_FREE(session, packet); + + listener->chanFwdCncl_state = libssh2_NB_state_sent; + } + + queued = _libssh2_list_first(&listener->queue); + while (queued) { + LIBSSH2_CHANNEL *next = _libssh2_list_next(&queued->node); + + rc = _libssh2_channel_free(queued); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + queued = next; + } + LIBSSH2_FREE(session, listener->host); + + /* remove this entry from the parent's list of listeners */ + _libssh2_list_remove(&listener->node); + + LIBSSH2_FREE(session, listener); + + return retcode; +} + +/* + * libssh2_channel_forward_cancel + * + * Stop listening on a remote port and free the listener + * Toss out any pending (un-accept()ed) connections + * + * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error + */ +LIBSSH2_API int +libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) +{ + int rc; + + if(!listener) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, listener->session, + _libssh2_channel_forward_cancel(listener)); + return rc; +} + +/* + * channel_forward_accept + * + * Accept a connection + */ +static LIBSSH2_CHANNEL * +channel_forward_accept(LIBSSH2_LISTENER *listener) +{ + int rc; + + do { + rc = _libssh2_transport_read(listener->session); + } while (rc > 0); + + if (_libssh2_list_first(&listener->queue)) { + LIBSSH2_CHANNEL *channel = _libssh2_list_first(&listener->queue); + + /* detach channel from listener's queue */ + _libssh2_list_remove(&channel->node); + + listener->queue_size--; + + /* add channel to session's channel list */ + _libssh2_list_add(&channel->session->channels, &channel->node); + + return channel; + } + + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for packet"); + } + else + _libssh2_error(listener->session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, + "Channel not found"); + return NULL; +} + +/* + * libssh2_channel_forward_accept + * + * Accept a connection + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener) +{ + LIBSSH2_CHANNEL *ptr; + + if(!listener) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, listener->session, + channel_forward_accept(listener)); + return ptr; + +} + +/* + * channel_setenv + * + * Set an environment variable prior to requesting a shell/program/subsystem + */ +static int channel_setenv(LIBSSH2_CHANNEL *channel, + const char *varname, unsigned int varname_len, + const char *value, unsigned int value_len) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s, *data; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + size_t data_len; + int rc; + + if (channel->setenv_state == libssh2_NB_state_idle) { + /* 21 = packet_type(1) + channel_id(4) + request_len(4) + + * request(3)"env" + want_reply(1) + varname_len(4) + value_len(4) */ + channel->setenv_packet_len = varname_len + value_len + 21; + + /* Zero the whole thing out */ + memset(&channel->setenv_packet_requirev_state, 0, + sizeof(channel->setenv_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Setting remote environment variable: %s=%s on " + "channel %lu/%lu", + varname, value, channel->local.id, channel->remote.id); + + s = channel->setenv_packet = + LIBSSH2_ALLOC(session, channel->setenv_packet_len); + if (!channel->setenv_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for setenv packet"); + } + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, "env", sizeof("env") - 1); + *(s++) = 0x01; + _libssh2_store_str(&s, varname, varname_len); + _libssh2_store_str(&s, value, value_len); + + channel->setenv_state = libssh2_NB_state_created; + } + + if (channel->setenv_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + channel->setenv_packet, + channel->setenv_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending setenv request"); + return rc; + } else if (rc) { + LIBSSH2_FREE(session, channel->setenv_packet); + channel->setenv_packet = NULL; + channel->setenv_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel-request packet for " + "setenv request"); + } + LIBSSH2_FREE(session, channel->setenv_packet); + channel->setenv_packet = NULL; + + _libssh2_htonu32(channel->setenv_local_channel, channel->local.id); + + channel->setenv_state = libssh2_NB_state_sent; + } + + if (channel->setenv_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->setenv_local_channel, 4, + &channel-> + setenv_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + if (rc) { + channel->setenv_state = libssh2_NB_state_idle; + return rc; + } + + if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { + LIBSSH2_FREE(session, data); + channel->setenv_state = libssh2_NB_state_idle; + return 0; + } + + LIBSSH2_FREE(session, data); + } + + channel->setenv_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel-setenv"); +} + +/* + * libssh2_channel_setenv_ex + * + * Set an environment variable prior to requesting a shell/program/subsystem + */ +LIBSSH2_API int +libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, + const char *varname, unsigned int varname_len, + const char *value, unsigned int value_len) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_setenv(channel, varname, varname_len, + value, value_len)); + return rc; +} + +/* + * channel_request_pty + * Duh... Request a PTY + */ +static int channel_request_pty(LIBSSH2_CHANNEL *channel, + const char *term, unsigned int term_len, + const char *modes, unsigned int modes_len, + int width, int height, + int width_px, int height_px) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + int rc; + + if (channel->reqPTY_state == libssh2_NB_state_idle) { + /* 41 = packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) + + * want_reply(1) + term_len(4) + width(4) + height(4) + width_px(4) + + * height_px(4) + modes_len(4) */ + if(term_len + modes_len > 256) { + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "term + mode lengths too large"); + } + + channel->reqPTY_packet_len = term_len + modes_len + 41; + + /* Zero the whole thing out */ + memset(&channel->reqPTY_packet_requirev_state, 0, + sizeof(channel->reqPTY_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Allocating tty on channel %lu/%lu", channel->local.id, + channel->remote.id); + + s = channel->reqPTY_packet; + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, (char *)"pty-req", sizeof("pty-req") - 1); + + *(s++) = 0x01; + + _libssh2_store_str(&s, term, term_len); + _libssh2_store_u32(&s, width); + _libssh2_store_u32(&s, height); + _libssh2_store_u32(&s, width_px); + _libssh2_store_u32(&s, height_px); + _libssh2_store_str(&s, modes, modes_len); + + channel->reqPTY_state = libssh2_NB_state_created; + } + + if (channel->reqPTY_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->reqPTY_packet, + channel->reqPTY_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending pty request"); + return rc; + } else if (rc) { + channel->reqPTY_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send pty-request packet"); + } + _libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id); + + channel->reqPTY_state = libssh2_NB_state_sent; + } + + if (channel->reqPTY_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + unsigned char code; + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->reqPTY_local_channel, 4, + &channel->reqPTY_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + channel->reqPTY_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Failed to require the PTY package"); + } + + code = data[0]; + + LIBSSH2_FREE(session, data); + channel->reqPTY_state = libssh2_NB_state_idle; + + if (code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel request-pty"); +} + +/* + * libssh2_channel_request_pty_ex + * Duh... Request a PTY + */ +LIBSSH2_API int +libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, + unsigned int term_len, const char *modes, + unsigned int modes_len, int width, int height, + int width_px, int height_px) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_request_pty(channel, term, term_len, modes, + modes_len, width, height, + width_px, height_px)); + return rc; +} + +static int +channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width, + int height, int width_px, int height_px) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + int rc; + int retcode = LIBSSH2_ERROR_PROTO; + + if (channel->reqPTY_state == libssh2_NB_state_idle) { + channel->reqPTY_packet_len = 39; + + /* Zero the whole thing out */ + memset(&channel->reqPTY_packet_requirev_state, 0, + sizeof(channel->reqPTY_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "changing tty size on channel %lu/%lu", + channel->local.id, + channel->remote.id); + + s = channel->reqPTY_packet; + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, (char *)"window-change", + sizeof("window-change") - 1); + *(s++) = 0x00; /* Don't reply */ + _libssh2_store_u32(&s, width); + _libssh2_store_u32(&s, height); + _libssh2_store_u32(&s, width_px); + _libssh2_store_u32(&s, height_px); + + channel->reqPTY_state = libssh2_NB_state_created; + } + + if (channel->reqPTY_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->reqPTY_packet, + channel->reqPTY_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending window-change request"); + return rc; + } else if (rc) { + channel->reqPTY_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send window-change packet"); + } + _libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id); + retcode = LIBSSH2_ERROR_NONE; + } + + channel->reqPTY_state = libssh2_NB_state_idle; + return retcode; +} + +LIBSSH2_API int +libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, int width, + int height, int width_px, int height_px) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_request_pty_size(channel, width, height, width_px, + height_px)); + return rc; +} + +/* Keep this an even number */ +#define LIBSSH2_X11_RANDOM_COOKIE_LEN 32 + +/* + * channel_x11_req + * Request X11 forwarding + */ +static int +channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection, + const char *auth_proto, const char *auth_cookie, + int screen_number) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + size_t proto_len = + auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1); + size_t cookie_len = + auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN; + int rc; + + if (channel->reqX11_state == libssh2_NB_state_idle) { + /* 30 = packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) + + * want_reply(1) + single_cnx(1) + proto_len(4) + cookie_len(4) + + * screen_num(4) */ + channel->reqX11_packet_len = proto_len + cookie_len + 30; + + /* Zero the whole thing out */ + memset(&channel->reqX11_packet_requirev_state, 0, + sizeof(channel->reqX11_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting x11-req for channel %lu/%lu: single=%d " + "proto=%s cookie=%s screen=%d", + channel->local.id, channel->remote.id, + single_connection, + auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", + auth_cookie ? auth_cookie : "", screen_number); + + s = channel->reqX11_packet = + LIBSSH2_ALLOC(session, channel->reqX11_packet_len); + if (!channel->reqX11_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for pty-request"); + } + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, "x11-req", sizeof("x11-req") - 1); + + *(s++) = 0x01; /* want_reply */ + *(s++) = single_connection ? 0x01 : 0x00; + + _libssh2_store_str(&s, auth_proto?auth_proto:"MIT-MAGIC-COOKIE-1", + proto_len); + + _libssh2_store_u32(&s, cookie_len); + if (auth_cookie) { + memcpy(s, auth_cookie, cookie_len); + } else { + int i; + /* note: the extra +1 below is necessary since the sprintf() + loop will always write 3 bytes so the last one will write + the trailing zero at the LIBSSH2_X11_RANDOM_COOKIE_LEN/2 + border */ + unsigned char buffer[(LIBSSH2_X11_RANDOM_COOKIE_LEN / 2) +1]; + + _libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); + for(i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) { + sprintf((char *)&s[i*2], "%02X", buffer[i]); + } + } + s += cookie_len; + + _libssh2_store_u32(&s, screen_number); + channel->reqX11_state = libssh2_NB_state_created; + } + + if (channel->reqX11_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->reqX11_packet, + channel->reqX11_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending X11-req packet"); + return rc; + } + if (rc) { + LIBSSH2_FREE(session, channel->reqX11_packet); + channel->reqX11_packet = NULL; + channel->reqX11_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send x11-req packet"); + } + LIBSSH2_FREE(session, channel->reqX11_packet); + channel->reqX11_packet = NULL; + + _libssh2_htonu32(channel->reqX11_local_channel, channel->local.id); + + channel->reqX11_state = libssh2_NB_state_sent; + } + + if (channel->reqX11_state == libssh2_NB_state_sent) { + size_t data_len; + unsigned char *data; + unsigned char code; + + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->reqX11_local_channel, 4, + &channel->reqX11_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + channel->reqX11_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "waiting for x11-req response packet"); + } + + code = data[0]; + LIBSSH2_FREE(session, data); + channel->reqX11_state = libssh2_NB_state_idle; + + if (code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel x11-req"); +} + +/* + * libssh2_channel_x11_req_ex + * Request X11 forwarding + */ +LIBSSH2_API int +libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, + const char *auth_proto, const char *auth_cookie, + int screen_number) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_x11_req(channel, single_connection, auth_proto, + auth_cookie, screen_number)); + return rc; +} + + +/* + * _libssh2_channel_process_startup + * + * Primitive for libssh2_channel_(shell|exec|subsystem) + */ +int +_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *request, size_t request_len, + const char *message, size_t message_len) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + int rc; + + if (channel->process_state == libssh2_NB_state_end) { + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "Channel can not be reused"); + } + + if (channel->process_state == libssh2_NB_state_idle) { + /* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */ + channel->process_packet_len = request_len + 10; + + /* Zero the whole thing out */ + memset(&channel->process_packet_requirev_state, 0, + sizeof(channel->process_packet_requirev_state)); + + if (message) + channel->process_packet_len += + 4; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "starting request(%s) on channel %lu/%lu, message=%s", + request, channel->local.id, channel->remote.id, + message?message:""); + s = channel->process_packet = + LIBSSH2_ALLOC(session, channel->process_packet_len); + if (!channel->process_packet) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for channel-process request"); + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, request, request_len); + *(s++) = 0x01; + + if (message) + _libssh2_store_u32(&s, message_len); + + channel->process_state = libssh2_NB_state_created; + } + + if (channel->process_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + channel->process_packet, + channel->process_packet_len, + (unsigned char *)message, message_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending channel request"); + return rc; + } + else if (rc) { + LIBSSH2_FREE(session, channel->process_packet); + channel->process_packet = NULL; + channel->process_state = libssh2_NB_state_end; + return _libssh2_error(session, rc, + "Unable to send channel request"); + } + LIBSSH2_FREE(session, channel->process_packet); + channel->process_packet = NULL; + + _libssh2_htonu32(channel->process_local_channel, channel->local.id); + + channel->process_state = libssh2_NB_state_sent; + } + + if (channel->process_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + unsigned char code; + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->process_local_channel, 4, + &channel->process_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + channel->process_state = libssh2_NB_state_end; + return _libssh2_error(session, rc, + "Failed waiting for channel success"); + } + + code = data[0]; + LIBSSH2_FREE(session, data); + channel->process_state = libssh2_NB_state_end; + + if (code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for " + "channel-process-startup"); +} + +/* + * libssh2_channel_process_startup + * + * Primitive for libssh2_channel_(shell|exec|subsystem) + */ +LIBSSH2_API int +libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *req, unsigned int req_len, + const char *msg, unsigned int msg_len) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_process_startup(channel, req, req_len, + msg, msg_len)); + return rc; +} + + +/* + * libssh2_channel_set_blocking + * + * Set a channel's BEHAVIOR blocking on or off. The socket will remain non- + * blocking. + */ +LIBSSH2_API void +libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking) +{ + if(channel) + (void) _libssh2_session_set_blocking(channel->session, blocking); +} + +/* + * _libssh2_channel_flush + * + * Flush data from one (or all) stream + * Returns number of bytes flushed, or negative on failure + */ +int +_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid) +{ + if (channel->flush_state == libssh2_NB_state_idle) { + LIBSSH2_PACKET *packet = + _libssh2_list_first(&channel->session->packets); + channel->flush_refund_bytes = 0; + channel->flush_flush_bytes = 0; + + while (packet) { + LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node); + unsigned char packet_type = packet->data[0]; + + if (((packet_type == SSH_MSG_CHANNEL_DATA) + || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) + && (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) { + /* It's our channel at least */ + long packet_stream_id = + (packet_type == SSH_MSG_CHANNEL_DATA) ? 0 : + _libssh2_ntohu32(packet->data + 5); + if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) + || ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) + && ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) + || (streamid == packet_stream_id))) + || ((packet_type == SSH_MSG_CHANNEL_DATA) + && (streamid == 0))) { + int bytes_to_flush = packet->data_len - packet->data_head; + + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Flushing %d bytes of data from stream " + "%lu on channel %lu/%lu", + bytes_to_flush, packet_stream_id, + channel->local.id, channel->remote.id); + + /* It's one of the streams we wanted to flush */ + channel->flush_refund_bytes += packet->data_len - 13; + channel->flush_flush_bytes += bytes_to_flush; + + LIBSSH2_FREE(channel->session, packet->data); + + /* remove this packet from the parent's list */ + _libssh2_list_remove(&packet->node); + LIBSSH2_FREE(channel->session, packet); + } + } + packet = next; + } + + channel->flush_state = libssh2_NB_state_created; + } + + channel->read_avail -= channel->flush_flush_bytes; + channel->remote.window_size -= channel->flush_flush_bytes; + + if (channel->flush_refund_bytes) { + int rc; + + rc = _libssh2_channel_receive_window_adjust(channel, + channel->flush_refund_bytes, + 1, NULL); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + channel->flush_state = libssh2_NB_state_idle; + + return channel->flush_flush_bytes; +} + +/* + * libssh2_channel_flush_ex + * + * Flush data from one (or all) stream + * Returns number of bytes flushed, or negative on failure + */ +LIBSSH2_API int +libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int stream) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_flush(channel, stream)); + return rc; +} + +/* + * libssh2_channel_get_exit_status + * + * Return the channel's program exit status. Note that the actual protocol + * provides the full 32bit this function returns. We cannot abuse it to + * return error values in case of errors so we return a zero if channel is + * NULL. + */ +LIBSSH2_API int +libssh2_channel_get_exit_status(LIBSSH2_CHANNEL *channel) +{ + if(!channel) + return 0; + + return channel->exit_status; +} + +/* + * libssh2_channel_get_exit_signal + * + * Get exit signal (without leading "SIG"), error message, and language + * tag into newly allocated buffers of indicated length. Caller can + * use NULL pointers to indicate that the value should not be set. The + * *_len variables are set if they are non-NULL even if the + * corresponding string parameter is NULL. Returns LIBSSH2_ERROR_NONE + * on success, or an API error code. + */ +LIBSSH2_API int +libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel, + char **exitsignal, + size_t *exitsignal_len, + char **errmsg, + size_t *errmsg_len, + char **langtag, + size_t *langtag_len) +{ + size_t namelen = 0; + + if (channel) { + LIBSSH2_SESSION *session = channel->session; + + if (channel->exit_signal) { + namelen = strlen(channel->exit_signal); + if (exitsignal) { + *exitsignal = LIBSSH2_ALLOC(session, namelen + 1); + if (!*exitsignal) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for signal name"); + } + memcpy(*exitsignal, channel->exit_signal, namelen); + (*exitsignal)[namelen] = '\0'; + } + if (exitsignal_len) + *exitsignal_len = namelen; + } else { + if (exitsignal) + *exitsignal = NULL; + if (exitsignal_len) + *exitsignal_len = 0; + } + + /* TODO: set error message and language tag */ + + if (errmsg) + *errmsg = NULL; + + if (errmsg_len) + *errmsg_len = 0; + + if (langtag) + *langtag = NULL; + + if (langtag_len) + *langtag_len = 0; + } + + return LIBSSH2_ERROR_NONE; +} + +/* + * _libssh2_channel_receive_window_adjust + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Calls _libssh2_error() ! + */ +int +_libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, + uint32_t adjustment, + unsigned char force, + unsigned int *store) +{ + int rc; + + if(store) + *store = channel->remote.window_size; + + if (channel->adjust_state == libssh2_NB_state_idle) { + if (!force + && (adjustment + channel->adjust_queue < + LIBSSH2_CHANNEL_MINADJUST)) { + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Queueing %lu bytes for receive window adjustment " + "for channel %lu/%lu", + adjustment, channel->local.id, channel->remote.id); + channel->adjust_queue += adjustment; + return 0; + } + + if (!adjustment && !channel->adjust_queue) { + return 0; + } + + adjustment += channel->adjust_queue; + channel->adjust_queue = 0; + + /* Adjust the window based on the block we just freed */ + channel->adjust_adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST; + _libssh2_htonu32(&channel->adjust_adjust[1], channel->remote.id); + _libssh2_htonu32(&channel->adjust_adjust[5], adjustment); + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Adjusting window %lu bytes for data on " + "channel %lu/%lu", + adjustment, channel->local.id, channel->remote.id); + + channel->adjust_state = libssh2_NB_state_created; + } + + rc = _libssh2_transport_send(channel->session, channel->adjust_adjust, 9, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(channel->session, rc, + "Would block sending window adjust"); + return rc; + } + else if (rc) { + channel->adjust_queue = adjustment; + return _libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send transfer-window adjustment " + "packet, deferring"); + } + else { + channel->remote.window_size += adjustment; + } + + channel->adjust_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_channel_receive_window_adjust + * + * DEPRECATED + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Returns the new size of the receive window (as understood by remote end). + * Note that it might return EAGAIN too which is highly stupid. + * + */ +LIBSSH2_API unsigned long +libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, + unsigned long adj, + unsigned char force) +{ + unsigned int window; + int rc; + + if(!channel) + return (unsigned long)LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_receive_window_adjust(channel, adj, + force, &window)); + + /* stupid - but this is how it was made to work before and this is just + kept for backwards compatibility */ + return rc?(unsigned long)rc:window; +} + +/* + * libssh2_channel_receive_window_adjust2 + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Stores the new size of the receive window in the data 'window' points to. + * + * Returns the "normal" error code: 0 for success, negative for failure. + */ +LIBSSH2_API int +libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel, + unsigned long adj, + unsigned char force, + unsigned int *window) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_receive_window_adjust(channel, adj, force, + window)); + return rc; +} + +int +_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode) +{ + if (channel->extData2_state == libssh2_NB_state_idle) { + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Setting channel %lu/%lu handle_extended_data" + " mode to %d", + channel->local.id, channel->remote.id, ignore_mode); + channel->remote.extended_data_ignore_mode = (char)ignore_mode; + + channel->extData2_state = libssh2_NB_state_created; + } + + if (channel->extData2_state == libssh2_NB_state_idle) { + if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) { + int rc = + _libssh2_channel_flush(channel, + LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA); + if(LIBSSH2_ERROR_EAGAIN == rc) + return rc; + } + } + + channel->extData2_state = libssh2_NB_state_idle; + return 0; +} + +/* + * libssh2_channel_handle_extended_data2() + * + */ +LIBSSH2_API int +libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, + int mode) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, _libssh2_channel_extended_data(channel, + mode)); + return rc; +} + +/* + * libssh2_channel_handle_extended_data + * + * DEPRECATED DO NOTE USE! + * + * How should extended data look to the calling app? Keep it in separate + * channels[_read() _read_stdder()]? (NORMAL) Merge the extended data to the + * standard data? [everything via _read()]? (MERGE) Ignore it entirely [toss + * out packets as they come in]? (IGNORE) + */ +LIBSSH2_API void +libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, + int ignore_mode) +{ + (void)libssh2_channel_handle_extended_data2(channel, ignore_mode); +} + + + +/* + * _libssh2_channel_read + * + * Read data from a channel + * + * It is important to not return 0 until the currently read channel is + * complete. If we read stuff from the wire but it was no payload data to fill + * in the buffer with, we MUST make sure to return LIBSSH2_ERROR_EAGAIN. + * + * The receive window must be maintained (enlarged) by the user of this + * function. + */ +ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, + char *buf, size_t buflen) +{ + LIBSSH2_SESSION *session = channel->session; + int rc; + int bytes_read = 0; + int bytes_want; + int unlink_packet; + LIBSSH2_PACKET *read_packet; + LIBSSH2_PACKET *read_next; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "channel_read() wants %d bytes from channel %lu/%lu " + "stream #%d", + (int) buflen, channel->local.id, channel->remote.id, + stream_id); + + /* expand the receiving window first if it has become too narrow */ + if( (channel->read_state == libssh2_NB_state_jump1) || + (channel->remote.window_size < channel->remote.window_size_initial / 4 * 3 + buflen) ) { + + uint32_t adjustment = channel->remote.window_size_initial + buflen - channel->remote.window_size; + if (adjustment < LIBSSH2_CHANNEL_MINADJUST) + adjustment = LIBSSH2_CHANNEL_MINADJUST; + + /* the actual window adjusting may not finish so we need to deal with + this special state here */ + channel->read_state = libssh2_NB_state_jump1; + rc = _libssh2_channel_receive_window_adjust(channel, adjustment, + 0, NULL); + if (rc) + return rc; + + channel->read_state = libssh2_NB_state_idle; + } + + /* Process all pending incoming packets. Tests prove that this way + produces faster transfers. */ + do { + rc = _libssh2_transport_read(session); + } while (rc > 0); + + if ((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) + return _libssh2_error(session, rc, "transport read"); + + read_packet = _libssh2_list_first(&session->packets); + while (read_packet && (bytes_read < (int) buflen)) { + /* previously this loop condition also checked for + !channel->remote.close but we cannot let it do this: + + We may have a series of packets to read that are still pending even + if a close has been received. Acknowledging the close too early + makes us flush buffers prematurely and loose data. + */ + + LIBSSH2_PACKET *readpkt = read_packet; + + /* In case packet gets destroyed during this iteration */ + read_next = _libssh2_list_next(&readpkt->node); + + channel->read_local_id = + _libssh2_ntohu32(readpkt->data + 1); + + /* + * Either we asked for a specific extended data stream + * (and data was available), + * or the standard stream (and data was available), + * or the standard stream with extended_data_merge + * enabled and data was available + */ + if ((stream_id + && (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == channel->read_local_id) + && (stream_id == (int) _libssh2_ntohu32(readpkt->data + 5))) + || (!stream_id && (readpkt->data[0] == SSH_MSG_CHANNEL_DATA) + && (channel->local.id == channel->read_local_id)) + || (!stream_id + && (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == channel->read_local_id) + && (channel->remote.extended_data_ignore_mode == + LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { + + /* figure out much more data we want to read */ + bytes_want = buflen - bytes_read; + unlink_packet = FALSE; + + if (bytes_want >= (int) (readpkt->data_len - readpkt->data_head)) { + /* we want more than this node keeps, so adjust the number and + delete this node after the copy */ + bytes_want = readpkt->data_len - readpkt->data_head; + unlink_packet = TRUE; + } + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "channel_read() got %d of data from %lu/%lu/%d%s", + bytes_want, channel->local.id, + channel->remote.id, stream_id, + unlink_packet?" [ul]":""); + + /* copy data from this struct to the target buffer */ + memcpy(&buf[bytes_read], + &readpkt->data[readpkt->data_head], bytes_want); + + /* advance pointer and counter */ + readpkt->data_head += bytes_want; + bytes_read += bytes_want; + + /* if drained, remove from list */ + if (unlink_packet) { + /* detach readpkt from session->packets list */ + _libssh2_list_remove(&readpkt->node); + + LIBSSH2_FREE(session, readpkt->data); + LIBSSH2_FREE(session, readpkt); + } + } + + /* check the next struct in the chain */ + read_packet = read_next; + } + + if (!bytes_read) { + /* If the channel is already at EOF or even closed, we need to signal + that back. We may have gotten that info while draining the incoming + transport layer until EAGAIN so we must not be fooled by that + return code. */ + if(channel->remote.eof || channel->remote.close) + return 0; + else if(rc != LIBSSH2_ERROR_EAGAIN) + return 0; + + /* if the transport layer said EAGAIN then we say so as well */ + return _libssh2_error(session, rc, "would block"); + } + + channel->read_avail -= bytes_read; + channel->remote.window_size -= bytes_read; + + return bytes_read; +} + +/* + * libssh2_channel_read_ex + * + * Read data from a channel (blocking or non-blocking depending on set state) + * + * When this is done non-blocking, it is important to not return 0 until the + * currently read channel is complete. If we read stuff from the wire but it + * was no payload data to fill in the buffer with, we MUST make sure to return + * LIBSSH2_ERROR_EAGAIN. + * + * This function will first make sure there's a receive window enough to + * receive a full buffer's wort of contents. An application may choose to + * adjust the receive window more to increase transfer performance. + */ +LIBSSH2_API ssize_t +libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, + size_t buflen) +{ + int rc; + unsigned long recv_window; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + recv_window = libssh2_channel_window_read_ex(channel, NULL, NULL); + + if(buflen > recv_window) { + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_receive_window_adjust(channel, buflen, + 1, NULL)); + } + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_read(channel, stream_id, buf, buflen)); + return rc; +} + +/* + * _libssh2_channel_packet_data_len + * + * Return the size of the data block of the current packet, or 0 if there + * isn't a packet. + */ +size_t +_libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id) +{ + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_PACKET *read_packet; + uint32_t read_local_id; + + read_packet = _libssh2_list_first(&session->packets); + if (read_packet == NULL) + return 0; + + while (read_packet) { + read_local_id = _libssh2_ntohu32(read_packet->data + 1); + + /* + * Either we asked for a specific extended data stream + * (and data was available), + * or the standard stream (and data was available), + * or the standard stream with extended_data_merge + * enabled and data was available + */ + if ((stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == read_local_id) + && (stream_id == (int) _libssh2_ntohu32(read_packet->data + 5))) + || + (!stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_DATA) + && (channel->local.id == read_local_id)) + || + (!stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == read_local_id) + && (channel->remote.extended_data_ignore_mode + == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) + { + return (read_packet->data_len - read_packet->data_head); + } + read_packet = _libssh2_list_next(&read_packet->node); + } + + return 0; +} + +/* + * _libssh2_channel_write + * + * Send data to a channel. Note that if this returns EAGAIN, the caller must + * call this function again with the SAME input arguments. + * + * Returns: number of bytes sent, or if it returns a negative number, that is + * the error code! + */ +ssize_t +_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, + const unsigned char *buf, size_t buflen) +{ + int rc = 0; + LIBSSH2_SESSION *session = channel->session; + ssize_t wrote = 0; /* counter for this specific this call */ + + /* In theory we could split larger buffers into several smaller packets + * but it turns out to be really hard and nasty to do while still offering + * the API/prototype. + * + * Instead we only deal with the first 32K in this call and for the parent + * function to call it again with the remainder! 32K is a conservative + * limit based on the text in RFC4253 section 6.1. + */ + if(buflen > 32700) + buflen = 32700; + + if (channel->write_state == libssh2_NB_state_idle) { + unsigned char *s = channel->write_packet; + + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Writing %d bytes on channel %lu/%lu, stream #%d", + (int) buflen, channel->local.id, channel->remote.id, + stream_id); + + if (channel->local.close) + return _libssh2_error(channel->session, + LIBSSH2_ERROR_CHANNEL_CLOSED, + "We've already closed this channel"); + else if (channel->local.eof) + return _libssh2_error(channel->session, + LIBSSH2_ERROR_CHANNEL_EOF_SENT, + "EOF has already been received, " + "data might be ignored"); + + /* drain the incoming flow first, mostly to make sure we get all + * pending window adjust packets */ + do + rc = _libssh2_transport_read(session); + while (rc > 0); + + if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) { + return _libssh2_error(channel->session, rc, + "Failure while draining incoming flow"); + } + + if(channel->local.window_size <= 0) { + /* there's no room for data so we stop */ + + /* Waiting on the socket to be writable would be wrong because we + * would be back here immediately, but a readable socket might + * herald an incoming window adjustment. + */ + session->socket_block_directions = LIBSSH2_SESSION_BLOCK_INBOUND; + + return (rc==LIBSSH2_ERROR_EAGAIN?rc:0); + } + + channel->write_bufwrite = buflen; + + *(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : + SSH_MSG_CHANNEL_DATA; + _libssh2_store_u32(&s, channel->remote.id); + if (stream_id) + _libssh2_store_u32(&s, stream_id); + + /* Don't exceed the remote end's limits */ + /* REMEMBER local means local as the SOURCE of the data */ + if (channel->write_bufwrite > channel->local.window_size) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Splitting write block due to %lu byte " + "window_size on %lu/%lu/%d", + channel->local.window_size, channel->local.id, + channel->remote.id, stream_id); + channel->write_bufwrite = channel->local.window_size; + } + if (channel->write_bufwrite > channel->local.packet_size) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Splitting write block due to %lu byte " + "packet_size on %lu/%lu/%d", + channel->local.packet_size, channel->local.id, + channel->remote.id, stream_id); + channel->write_bufwrite = channel->local.packet_size; + } + /* store the size here only, the buffer is passed in as-is to + _libssh2_transport_send() */ + _libssh2_store_u32(&s, channel->write_bufwrite); + channel->write_packet_len = s - channel->write_packet; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Sending %d bytes on channel %lu/%lu, stream_id=%d", + (int) channel->write_bufwrite, channel->local.id, + channel->remote.id, stream_id); + + channel->write_state = libssh2_NB_state_created; + } + + if (channel->write_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->write_packet, + channel->write_packet_len, + buf, channel->write_bufwrite); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, rc, + "Unable to send channel data"); + } + else if (rc) { + channel->write_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send channel data"); + } + /* Shrink local window size */ + channel->local.window_size -= channel->write_bufwrite; + + wrote += channel->write_bufwrite; + + /* Since _libssh2_transport_write() succeeded, we must return + now to allow the caller to provide the next chunk of data. + + We cannot move on to send the next piece of data that may + already have been provided in this same function call, as we + risk getting EAGAIN for that and we can't return information + both about sent data as well as EAGAIN. So, by returning short + now, the caller will call this function again with new data to + send */ + + channel->write_state = libssh2_NB_state_idle; + + return wrote; + } + + return LIBSSH2_ERROR_INVAL; /* reaching this point is really bad */ +} + +/* + * libssh2_channel_write_ex + * + * Send data to a channel + */ +LIBSSH2_API ssize_t +libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, + const char *buf, size_t buflen) +{ + ssize_t rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_write(channel, stream_id, + (unsigned char *)buf, buflen)); + return rc; +} + +/* + * channel_send_eof + * + * Send EOF on channel + */ +static int channel_send_eof(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char packet[5]; /* packet_type(1) + channelno(4) */ + int rc; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, "Sending EOF on channel %lu/%lu", + channel->local.id, channel->remote.id); + packet[0] = SSH_MSG_CHANNEL_EOF; + _libssh2_htonu32(packet + 1, channel->remote.id); + rc = _libssh2_transport_send(session, packet, 5, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending EOF"); + return rc; + } + else if (rc) { + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send EOF on channel"); + } + channel->local.eof = 1; + + return 0; +} + +/* + * libssh2_channel_send_eof + * + * Send EOF on channel + */ +LIBSSH2_API int +libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, channel_send_eof(channel)); + return rc; +} + +/* + * libssh2_channel_eof + * + * Read channel's eof status + */ +LIBSSH2_API int +libssh2_channel_eof(LIBSSH2_CHANNEL * channel) +{ + LIBSSH2_SESSION *session; + LIBSSH2_PACKET *packet; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + session = channel->session; + packet = _libssh2_list_first(&session->packets); + + while (packet) { + if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) + || (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) + && (channel->local.id == _libssh2_ntohu32(packet->data + 1))) { + /* There's data waiting to be read yet, mask the EOF status */ + return 0; + } + packet = _libssh2_list_next(&packet->node); + } + + return channel->remote.eof; +} + +/* + * channel_wait_eof + * + * Awaiting channel EOF + */ +static int channel_wait_eof(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + int rc; + + if (channel->wait_eof_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Awaiting close of channel %lu/%lu", channel->local.id, + channel->remote.id); + + channel->wait_eof_state = libssh2_NB_state_created; + } + + /* + * While channel is not eof, read more packets from the network. + * Either the EOF will be set or network timeout will occur. + */ + do { + if (channel->remote.eof) { + break; + } + rc = _libssh2_transport_read(session); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if (rc < 0) { + channel->wait_eof_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "_libssh2_transport_read() bailed out!"); + } + } while (1); + + channel->wait_eof_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_channel_wait_eof + * + * Awaiting channel EOF + */ +LIBSSH2_API int +libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, channel_wait_eof(channel)); + return rc; +} + +int _libssh2_channel_close(LIBSSH2_CHANNEL * channel) +{ + LIBSSH2_SESSION *session = channel->session; + int rc = 0; + + if (channel->local.close) { + /* Already closed, act like we sent another close, + * even though we didn't... shhhhhh */ + channel->close_state = libssh2_NB_state_idle; + return 0; + } + + if (!channel->local.eof) { + if ((rc = channel_send_eof(channel))) { + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + _libssh2_error(session, rc, + "Unable to send EOF, but closing channel anyway"); + } + } + + /* ignore if we have received a remote eof or not, as it is now too + late for us to wait for it. Continue closing! */ + + if (channel->close_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, "Closing channel %lu/%lu", + channel->local.id, channel->remote.id); + + channel->close_packet[0] = SSH_MSG_CHANNEL_CLOSE; + _libssh2_htonu32(channel->close_packet + 1, channel->remote.id); + + channel->close_state = libssh2_NB_state_created; + } + + if (channel->close_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->close_packet, 5, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending close-channel"); + return rc; + + } else if (rc) { + _libssh2_error(session, rc, + "Unable to send close-channel request, " + "but closing anyway"); + /* skip waiting for the response and fall through to + LIBSSH2_CHANNEL_CLOSE below */ + + } else + channel->close_state = libssh2_NB_state_sent; + } + + if (channel->close_state == libssh2_NB_state_sent) { + /* We must wait for the remote SSH_MSG_CHANNEL_CLOSE message */ + + while (!channel->remote.close && !rc && + (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED)) + rc = _libssh2_transport_read(session); + } + + if(rc != LIBSSH2_ERROR_EAGAIN) { + /* set the local close state first when we're perfectly confirmed to not + do any more EAGAINs */ + channel->local.close = 1; + + /* We call the callback last in this function to make it keep the local + data as long as EAGAIN is returned. */ + if (channel->close_cb) { + LIBSSH2_CHANNEL_CLOSE(session, channel); + } + + channel->close_state = libssh2_NB_state_idle; + } + + /* return 0 or an error */ + return rc>=0?0:rc; +} + +/* + * libssh2_channel_close + * + * Close a channel + */ +LIBSSH2_API int +libssh2_channel_close(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, _libssh2_channel_close(channel) ); + return rc; +} + +/* + * channel_wait_closed + * + * Awaiting channel close after EOF + */ +static int channel_wait_closed(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + int rc; + + if (!libssh2_channel_eof(channel)) { + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "libssh2_channel_wait_closed() invoked when " + "channel is not in EOF state"); + } + + if (channel->wait_closed_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Awaiting close of channel %lu/%lu", channel->local.id, + channel->remote.id); + + channel->wait_closed_state = libssh2_NB_state_created; + } + + /* + * While channel is not closed, read more packets from the network. + * Either the channel will be closed or network timeout will occur. + */ + if (!channel->remote.close) { + do { + rc = _libssh2_transport_read(session); + if (channel->remote.close) + /* it is now closed, move on! */ + break; + } while (rc > 0); + if(rc < 0) + return rc; + } + + channel->wait_closed_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_channel_wait_closed + * + * Awaiting channel close after EOF + */ +LIBSSH2_API int +libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, channel_wait_closed(channel)); + return rc; +} + +/* + * _libssh2_channel_free + * + * Make sure a channel is closed, then remove the channel from the session + * and free its resource(s) + * + * Returns 0 on success, negative on failure + */ +int _libssh2_channel_free(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char channel_id[4]; + unsigned char *data; + size_t data_len; + int rc; + + assert(session); + + if (channel->free_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Freeing channel %lu/%lu resources", channel->local.id, + channel->remote.id); + + channel->free_state = libssh2_NB_state_created; + } + + /* Allow channel freeing even when the socket has lost its connection */ + if (!channel->local.close + && (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) { + rc = _libssh2_channel_close(channel); + + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + /* ignore all other errors as they otherwise risk blocking the channel + free from happening */ + } + + channel->free_state = libssh2_NB_state_idle; + + if (channel->exit_signal) { + LIBSSH2_FREE(session, channel->exit_signal); + } + + /* + * channel->remote.close *might* not be set yet, Well... + * We've sent the close packet, what more do you want? + * Just let packet_add ignore it when it finally arrives + */ + + /* Clear out packets meant for this channel */ + _libssh2_htonu32(channel_id, channel->local.id); + while ((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, &data, + &data_len, 1, channel_id, 4) >= 0) + || + (_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, + &data_len, 1, channel_id, 4) >= 0)) { + LIBSSH2_FREE(session, data); + } + + /* free "channel_type" */ + if (channel->channel_type) { + LIBSSH2_FREE(session, channel->channel_type); + } + + /* Unlink from channel list */ + _libssh2_list_remove(&channel->node); + + /* + * Make sure all memory used in the state variables are free + */ + if (channel->setenv_packet) { + LIBSSH2_FREE(session, channel->setenv_packet); + } + if (channel->reqX11_packet) { + LIBSSH2_FREE(session, channel->reqX11_packet); + } + if (channel->process_packet) { + LIBSSH2_FREE(session, channel->process_packet); + } + + LIBSSH2_FREE(session, channel); + + return 0; +} + +/* + * libssh2_channel_free + * + * Make sure a channel is closed, then remove the channel from the session + * and free its resource(s) + * + * Returns 0 on success, negative on failure + */ +LIBSSH2_API int +libssh2_channel_free(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, _libssh2_channel_free(channel)); + return rc; +} +/* + * libssh2_channel_window_read_ex + * + * Check the status of the read window. Returns the number of bytes which the + * remote end may send without overflowing the window limit read_avail (if + * passed) will be populated with the number of bytes actually available to be + * read window_size_initial (if passed) will be populated with the + * window_size_initial as defined by the channel_open request + */ +LIBSSH2_API unsigned long +libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, + unsigned long *read_avail, + unsigned long *window_size_initial) +{ + if(!channel) + return 0; /* no channel, no window! */ + + if (window_size_initial) { + *window_size_initial = channel->remote.window_size_initial; + } + + if (read_avail) { + size_t bytes_queued = 0; + LIBSSH2_PACKET *packet = + _libssh2_list_first(&channel->session->packets); + + while (packet) { + unsigned char packet_type = packet->data[0]; + + if (((packet_type == SSH_MSG_CHANNEL_DATA) + || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) + && (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) { + bytes_queued += packet->data_len - packet->data_head; + } + + packet = _libssh2_list_next(&packet->node); + } + + *read_avail = bytes_queued; + } + + return channel->remote.window_size; +} + +/* + * libssh2_channel_window_write_ex + * + * Check the status of the write window Returns the number of bytes which may + * be safely written on the channel without blocking window_size_initial (if + * passed) will be populated with the size of the initial window as defined by + * the channel_open request + */ +LIBSSH2_API unsigned long +libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, + unsigned long *window_size_initial) +{ + if(!channel) + return 0; /* no channel, no window! */ + + if (window_size_initial) { + /* For locally initiated channels this is very often 0, so it's not + * *that* useful as information goes */ + *window_size_initial = channel->local.window_size_initial; + } + + return channel->local.window_size; +} diff --git a/libssh2/src/channel.h b/libssh2/src/channel.h new file mode 100644 index 000000000..dc0ee3764 --- /dev/null +++ b/libssh2/src/channel.h @@ -0,0 +1,141 @@ +#ifndef __LIBSSH2_CHANNEL_H +#define __LIBSSH2_CHANNEL_H +/* Copyright (c) 2008-2010 by Daniel Stenberg + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +/* + * _libssh2_channel_receive_window_adjust + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Always non-blocking. + */ +int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, + uint32_t adjustment, + unsigned char force, + unsigned int *store); + +/* + * _libssh2_channel_flush + * + * Flush data from one (or all) stream + * Returns number of bytes flushed, or negative on failure + */ +int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid); + +/* + * _libssh2_channel_free + * + * Make sure a channel is closed, then remove the channel from the session + * and free its resource(s) + * + * Returns 0 on success, negative on failure + */ +int _libssh2_channel_free(LIBSSH2_CHANNEL *channel); + +int +_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode); + +/* + * _libssh2_channel_write + * + * Send data to a channel + */ +ssize_t +_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, + const unsigned char *buf, size_t buflen); + +/* + * _libssh2_channel_open + * + * Establish a generic session channel + */ +LIBSSH2_CHANNEL * +_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type, + uint32_t channel_type_len, + uint32_t window_size, + uint32_t packet_size, + const unsigned char *message, size_t message_len); + + +/* + * _libssh2_channel_process_startup + * + * Primitive for libssh2_channel_(shell|exec|subsystem) + */ +int +_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *request, size_t request_len, + const char *message, size_t message_len); + +/* + * _libssh2_channel_read + * + * Read data from a channel + * + * It is important to not return 0 until the currently read channel is + * complete. If we read stuff from the wire but it was no payload data to fill + * in the buffer with, we MUST make sure to return PACKET_EAGAIN. + */ +ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, + char *buf, size_t buflen); + +uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session); + +LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session, + uint32_t channel_id); + +size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, + int stream_id); + +int _libssh2_channel_close(LIBSSH2_CHANNEL * channel); + +/* + * _libssh2_channel_forward_cancel + * + * Stop listening on a remote port and free the listener + * Toss out any pending (un-accept()ed) connections + * + * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error + */ +int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); + +#endif /* __LIBSSH2_CHANNEL_H */ + diff --git a/libssh2/src/comp.c b/libssh2/src/comp.c new file mode 100644 index 000000000..4560188bb --- /dev/null +++ b/libssh2/src/comp.c @@ -0,0 +1,366 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2010-2014, Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#ifdef LIBSSH2_HAVE_ZLIB +# include +#endif + +#include "comp.h" + +/* ******** + * none * + ******** */ + +/* + * comp_method_none_comp + * + * Minimalist compression: Absolutely none + */ +static int +comp_method_none_comp(LIBSSH2_SESSION *session, + unsigned char *dest, + size_t *dest_len, + const unsigned char *src, + size_t src_len, + void **abstract) +{ + (void) session; + (void) abstract; + (void) dest; + (void) dest_len; + (void) src; + (void) src_len; + + return 0; +} + +/* + * comp_method_none_decomp + * + * Minimalist decompression: Absolutely none + */ +static int +comp_method_none_decomp(LIBSSH2_SESSION * session, + unsigned char **dest, + size_t *dest_len, + size_t payload_limit, + const unsigned char *src, + size_t src_len, void **abstract) +{ + (void) session; + (void) payload_limit; + (void) abstract; + *dest = (unsigned char *) src; + *dest_len = src_len; + return 0; +} + + + +static const LIBSSH2_COMP_METHOD comp_method_none = { + "none", + 0, /* not really compressing */ + 0, /* isn't used in userauth, go figure */ + NULL, + comp_method_none_comp, + comp_method_none_decomp, + NULL +}; + +#ifdef LIBSSH2_HAVE_ZLIB +/* ******** + * zlib * + ******** */ + +/* Memory management wrappers + * Yes, I realize we're doing a callback to a callback, + * Deal... + */ + +static voidpf +comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size) +{ + LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque; + + return (voidpf) LIBSSH2_ALLOC(session, items * size); +} + +static void +comp_method_zlib_free(voidpf opaque, voidpf address) +{ + LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque; + + LIBSSH2_FREE(session, address); +} + + + +/* libssh2_comp_method_zlib_init + * All your bandwidth are belong to us (so save some) + */ +static int +comp_method_zlib_init(LIBSSH2_SESSION * session, int compr, + void **abstract) +{ + z_stream *strm; + int status; + + strm = LIBSSH2_CALLOC(session, sizeof(z_stream)); + if (!strm) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "zlib compression/decompression"); + } + + strm->opaque = (voidpf) session; + strm->zalloc = (alloc_func) comp_method_zlib_alloc; + strm->zfree = (free_func) comp_method_zlib_free; + if (compr) { + /* deflate */ + status = deflateInit(strm, Z_DEFAULT_COMPRESSION); + } else { + /* inflate */ + status = inflateInit(strm); + } + + if (status != Z_OK) { + LIBSSH2_FREE(session, strm); + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unhandled zlib error %d", status); + return LIBSSH2_ERROR_COMPRESS; + } + *abstract = strm; + + return LIBSSH2_ERROR_NONE; +} + +/* + * libssh2_comp_method_zlib_comp + * + * Compresses source to destination. Without allocation. + */ +static int +comp_method_zlib_comp(LIBSSH2_SESSION *session, + unsigned char *dest, + + /* dest_len is a pointer to allow this function to + update it with the final actual size used */ + size_t *dest_len, + const unsigned char *src, + size_t src_len, + void **abstract) +{ + z_stream *strm = *abstract; + int out_maxlen = *dest_len; + int status; + + strm->next_in = (unsigned char *) src; + strm->avail_in = src_len; + strm->next_out = dest; + strm->avail_out = out_maxlen; + + status = deflate(strm, Z_PARTIAL_FLUSH); + + if ((status == Z_OK) && (strm->avail_out > 0)) { + *dest_len = out_maxlen - strm->avail_out; + return 0; + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unhandled zlib compression error %d, avail_out", status, strm->avail_out); + return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure"); +} + +/* + * libssh2_comp_method_zlib_decomp + * + * Decompresses source to destination. Allocates the output memory. + */ +static int +comp_method_zlib_decomp(LIBSSH2_SESSION * session, + unsigned char **dest, + size_t *dest_len, + size_t payload_limit, + const unsigned char *src, + size_t src_len, void **abstract) +{ + z_stream *strm = *abstract; + /* A short-term alloc of a full data chunk is better than a series of + reallocs */ + char *out; + int out_maxlen = 4 * src_len; + + /* If strm is null, then we have not yet been initialized. */ + if (strm == NULL) + return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS, + "decompression uninitialized");; + + /* In practice they never come smaller than this */ + if (out_maxlen < 25) + out_maxlen = 25; + + if (out_maxlen > (int) payload_limit) + out_maxlen = payload_limit; + + strm->next_in = (unsigned char *) src; + strm->avail_in = src_len; + strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen); + out = (char *) strm->next_out; + strm->avail_out = out_maxlen; + if (!strm->next_out) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate decompression buffer"); + + /* Loop until it's all inflated or hit error */ + for (;;) { + int status; + size_t out_ofs; + char *newout; + + status = inflate(strm, Z_PARTIAL_FLUSH); + + if (status == Z_OK) { + if (strm->avail_out > 0) + /* status is OK and the output buffer has not been exhausted so we're done */ + break; + } else if (status == Z_BUF_ERROR) { + /* the input data has been exhausted so we are done */ + break; + } else { + /* error state */ + LIBSSH2_FREE(session, out); + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unhandled zlib error %d", status); + return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, + "decompression failure"); + } + + if (out_maxlen >= (int) payload_limit) { + LIBSSH2_FREE(session, out); + return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, + "Excessive growth in decompression phase"); + } + + /* If we get here we need to grow the output buffer and try again */ + out_ofs = out_maxlen - strm->avail_out; + out_maxlen *= 2; + newout = LIBSSH2_REALLOC(session, out, out_maxlen); + if (!newout) { + LIBSSH2_FREE(session, out); + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to expand decompression buffer"); + } + out = newout; + strm->next_out = (unsigned char *) out + out_ofs; + strm->avail_out = out_maxlen - out_ofs; + } + + *dest = (unsigned char *) out; + *dest_len = out_maxlen - strm->avail_out; + + return 0; +} + + +/* libssh2_comp_method_zlib_dtor + * All done, no more compression for you + */ +static int +comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract) +{ + z_stream *strm = *abstract; + + if (strm) { + if (compr) + deflateEnd(strm); + else + inflateEnd(strm); + LIBSSH2_FREE(session, strm); + } + + *abstract = NULL; + return 0; +} + +static const LIBSSH2_COMP_METHOD comp_method_zlib = { + "zlib", + 1, /* yes, this compresses */ + 1, /* do compression during userauth */ + comp_method_zlib_init, + comp_method_zlib_comp, + comp_method_zlib_decomp, + comp_method_zlib_dtor, +}; + +static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = { + "zlib@openssh.com", + 1, /* yes, this compresses */ + 0, /* don't use compression during userauth */ + comp_method_zlib_init, + comp_method_zlib_comp, + comp_method_zlib_decomp, + comp_method_zlib_dtor, +}; +#endif /* LIBSSH2_HAVE_ZLIB */ + +/* If compression is enabled by the API, then this array is used which then + may allow compression if zlib is available at build time */ +static const LIBSSH2_COMP_METHOD *comp_methods[] = { +#ifdef LIBSSH2_HAVE_ZLIB + &comp_method_zlib, + &comp_method_zlib_openssh, +#endif /* LIBSSH2_HAVE_ZLIB */ + &comp_method_none, + NULL +}; + +/* If compression is disabled by the API, then this array is used */ +static const LIBSSH2_COMP_METHOD *no_comp_methods[] = { + &comp_method_none, + NULL +}; + +const LIBSSH2_COMP_METHOD ** +_libssh2_comp_methods(LIBSSH2_SESSION *session) +{ + if(session->flag.compress) + return comp_methods; + else + return no_comp_methods; +} diff --git a/libssh2/src/comp.h b/libssh2/src/comp.h new file mode 100644 index 000000000..8edc15029 --- /dev/null +++ b/libssh2/src/comp.h @@ -0,0 +1,45 @@ +#ifndef __LIBSSH2_COMP_H +#define __LIBSSH2_COMP_H + +/* Copyright (C) 2009-2010 by Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" + +const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session); + +#endif /* __LIBSSH2_COMP_H */ diff --git a/libssh2/src/crypt.c b/libssh2/src/crypt.c new file mode 100644 index 000000000..931ae8b80 --- /dev/null +++ b/libssh2/src/crypt.c @@ -0,0 +1,336 @@ +/* Copyright (c) 2009, 2010 Simon Josefsson + * Copyright (c) 2004-2007, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_CRYPT_NONE + +/* crypt_none_crypt + * Minimalist cipher: VERY secure *wink* + */ +static int +crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf, + void **abstract) +{ + /* Do nothing to the data! */ + return 0; +} + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = { + "none", + 8, /* blocksize (SSH2 defines minimum blocksize as 8) */ + 0, /* iv_len */ + 0, /* secret_len */ + 0, /* flags */ + NULL, + crypt_none_crypt, + NULL +}; +#endif /* LIBSSH2_CRYPT_NONE */ + +struct crypt_ctx +{ + int encrypt; + _libssh2_cipher_type(algo); + _libssh2_cipher_ctx h; +}; + +static int +crypt_init(LIBSSH2_SESSION * session, + const LIBSSH2_CRYPT_METHOD * method, + unsigned char *iv, int *free_iv, + unsigned char *secret, int *free_secret, + int encrypt, void **abstract) +{ + struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, + sizeof(struct crypt_ctx)); + if (!ctx) + return LIBSSH2_ERROR_ALLOC; + + ctx->encrypt = encrypt; + ctx->algo = method->algo; + if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) { + LIBSSH2_FREE(session, ctx); + return -1; + } + *abstract = ctx; + *free_iv = 1; + *free_secret = 1; + return 0; +} + +static int +crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block, + size_t blocksize, void **abstract) +{ + struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract; + (void) session; + return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block, + blocksize); +} + +static int +crypt_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + struct crypt_ctx **cctx = (struct crypt_ctx **) abstract; + if (cctx && *cctx) { + _libssh2_cipher_dtor(&(*cctx)->h); + LIBSSH2_FREE(session, *cctx); + *abstract = NULL; + } + return 0; +} + +#if LIBSSH2_AES_CTR +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = { + "aes128-ctr", + 16, /* blocksize */ + 16, /* initial value length */ + 16, /* secret length -- 16*8 == 128bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes128ctr +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = { + "aes192-ctr", + 16, /* blocksize */ + 16, /* initial value length */ + 24, /* secret length -- 24*8 == 192bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes192ctr +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = { + "aes256-ctr", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes256ctr +}; +#endif + +#if LIBSSH2_AES +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { + "aes128-cbc", + 16, /* blocksize */ + 16, /* initial value length */ + 16, /* secret length -- 16*8 == 128bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes128 +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = { + "aes192-cbc", + 16, /* blocksize */ + 16, /* initial value length */ + 24, /* secret length -- 24*8 == 192bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes192 +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = { + "aes256-cbc", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes256 +}; + +/* rijndael-cbc@lysator.liu.se == aes256-cbc */ +static const LIBSSH2_CRYPT_METHOD + libssh2_crypt_method_rijndael_cbc_lysator_liu_se = { + "rijndael-cbc@lysator.liu.se", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes256 +}; +#endif /* LIBSSH2_AES */ + +#if LIBSSH2_BLOWFISH +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = { + "blowfish-cbc", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_blowfish +}; +#endif /* LIBSSH2_BLOWFISH */ + +#if LIBSSH2_RC4 +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { + "arcfour", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_arcfour +}; + +static int +crypt_init_arcfour128(LIBSSH2_SESSION * session, + const LIBSSH2_CRYPT_METHOD * method, + unsigned char *iv, int *free_iv, + unsigned char *secret, int *free_secret, + int encrypt, void **abstract) +{ + int rc; + + rc = crypt_init (session, method, iv, free_iv, secret, free_secret, + encrypt, abstract); + if (rc == 0) { + struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract; + unsigned char block[8]; + size_t discard = 1536; + for (; discard; discard -= 8) + _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block, + method->blocksize); + } + + return rc; +} + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = { + "arcfour128", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init_arcfour128, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_arcfour +}; +#endif /* LIBSSH2_RC4 */ + +#if LIBSSH2_CAST +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { + "cast128-cbc", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_cast5 +}; +#endif /* LIBSSH2_CAST */ + +#if LIBSSH2_3DES +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { + "3des-cbc", + 8, /* blocksize */ + 8, /* initial value length */ + 24, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_3des +}; +#endif + +static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = { +#if LIBSSH2_AES_CTR + &libssh2_crypt_method_aes128_ctr, + &libssh2_crypt_method_aes192_ctr, + &libssh2_crypt_method_aes256_ctr, +#endif /* LIBSSH2_AES */ +#if LIBSSH2_AES + &libssh2_crypt_method_aes256_cbc, + &libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */ + &libssh2_crypt_method_aes192_cbc, + &libssh2_crypt_method_aes128_cbc, +#endif /* LIBSSH2_AES */ +#if LIBSSH2_BLOWFISH + &libssh2_crypt_method_blowfish_cbc, +#endif /* LIBSSH2_BLOWFISH */ +#if LIBSSH2_RC4 + &libssh2_crypt_method_arcfour128, + &libssh2_crypt_method_arcfour, +#endif /* LIBSSH2_RC4 */ +#if LIBSSH2_CAST + &libssh2_crypt_method_cast128_cbc, +#endif /* LIBSSH2_CAST */ +#if LIBSSH2_3DES + &libssh2_crypt_method_3des_cbc, +#endif /* LIBSSH2_DES */ +#ifdef LIBSSH2_CRYPT_NONE + &libssh2_crypt_method_none, +#endif + NULL +}; + +/* Expose to kex.c */ +const LIBSSH2_CRYPT_METHOD ** +libssh2_crypt_methods(void) +{ + return _libssh2_crypt_methods; +} diff --git a/libssh2/src/crypto.h b/libssh2/src/crypto.h new file mode 100644 index 000000000..aa997a307 --- /dev/null +++ b/libssh2/src/crypto.h @@ -0,0 +1,150 @@ +/* Copyright (C) 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. + * Copyright (C) 2010 Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ +#ifndef LIBSSH2_CRYPTO_H +#define LIBSSH2_CRYPTO_H + +#ifdef LIBSSH2_OPENSSL +#include "openssl.h" +#endif + +#ifdef LIBSSH2_LIBGCRYPT +#include "libgcrypt.h" +#endif + +#ifdef LIBSSH2_WINCNG +#include "wincng.h" +#endif + +#ifdef LIBSSH2_OS400QC3 +#include "os400qc3.h" +#endif + +#ifdef LIBSSH2_MBEDTLS +#include "mbedtls.h" +#endif + +int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen); +int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase); +int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, unsigned long m_len); +int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len); +int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase); + +#if LIBSSH2_DSA +int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *gdata, + unsigned long glen, + const unsigned char *ydata, + unsigned long ylen, + const unsigned char *x, unsigned long x_len); +int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase); +int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len); +int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *sig); +int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase); +#endif + +int _libssh2_cipher_init(_libssh2_cipher_ctx * h, + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, int encrypt); + +int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blocksize); + +int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase); +int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase); + +void _libssh2_init_aes_ctr(void); + +#endif diff --git a/libssh2/src/global.c b/libssh2/src/global.c new file mode 100644 index 000000000..dc45e7003 --- /dev/null +++ b/libssh2/src/global.c @@ -0,0 +1,78 @@ +/* Copyright (c) 2010 Lars Nordin + * Copyright (C) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +static int _libssh2_initialized = 0; +static int _libssh2_init_flags = 0; + +LIBSSH2_API int +libssh2_init(int flags) +{ + if (_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) { + libssh2_crypto_init(); + _libssh2_init_aes_ctr(); + } + + _libssh2_initialized++; + _libssh2_init_flags |= flags; + + return 0; +} + +LIBSSH2_API void +libssh2_exit(void) +{ + if (_libssh2_initialized == 0) + return; + + _libssh2_initialized--; + + if (!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) { + libssh2_crypto_exit(); + } + + return; +} + +void +_libssh2_init_if_needed(void) +{ + if (_libssh2_initialized == 0) + (void)libssh2_init (0); +} diff --git a/libssh2/src/hostkey.c b/libssh2/src/hostkey.c new file mode 100644 index 000000000..2a0a8f943 --- /dev/null +++ b/libssh2/src/hostkey.c @@ -0,0 +1,573 @@ +/* Copyright (c) 2004-2006, Sara Golemon + * Copyright (c) 2009-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#if LIBSSH2_RSA +/* *********** + * ssh-rsa * + *********** */ + +static int hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, + void **abstract); + +/* + * hostkey_method_ssh_rsa_init + * + * Initialize the server hostkey working area with e/n pair + */ +static int +hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session, + const unsigned char *hostkey_data, + size_t hostkey_data_len, + void **abstract) +{ + libssh2_rsa_ctx *rsactx; + const unsigned char *s, *e, *n; + unsigned long len, e_len, n_len; + int ret; + + (void) hostkey_data_len; + + if (*abstract) { + hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } + + s = hostkey_data; + len = _libssh2_ntohu32(s); + s += 4; + + if (len != 7 || strncmp((char *) s, "ssh-rsa", 7) != 0) { + return -1; + } + s += 7; + + e_len = _libssh2_ntohu32(s); + s += 4; + + e = s; + s += e_len; + n_len = _libssh2_ntohu32(s); + s += 4; + n = s; + + ret = _libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0); + if (ret) { + return -1; + } + + *abstract = rsactx; + + return 0; +} + +/* + * hostkey_method_ssh_rsa_initPEM + * + * Load a Private Key from a PEM file + */ +static int +hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_rsa_ctx *rsactx; + int ret; + + if (*abstract) { + hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_rsa_new_private(&rsactx, session, privkeyfile, passphrase); + if (ret) { + return -1; + } + + *abstract = rsactx; + + return 0; +} + +/* + * hostkey_method_ssh_rsa_initPEMFromMemory + * + * Load a Private Key from a memory + */ +static int +hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session, + const char *privkeyfiledata, + size_t privkeyfiledata_len, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_rsa_ctx *rsactx; + int ret; + + if (*abstract) { + hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_rsa_new_private_frommemory(&rsactx, session, + privkeyfiledata, + privkeyfiledata_len, passphrase); + if (ret) { + return -1; + } + + *abstract = rsactx; + + return 0; +} + +/* + * hostkey_method_ssh_rsa_sign + * + * Verify signature created by remote + */ +static int +hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session, + const unsigned char *sig, + size_t sig_len, + const unsigned char *m, + size_t m_len, void **abstract) +{ + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); + (void) session; + + /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */ + sig += 15; + sig_len -= 15; + return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len); +} + +/* + * hostkey_method_ssh_rsa_signv + * + * Construct a signature from an array of vectors + */ +static int +hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec datavec[], + void **abstract) +{ + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); + +#ifdef _libssh2_rsa_sha1_signv + return _libssh2_rsa_sha1_signv(session, signature, signature_len, + veccount, datavec, rsactx); +#else + int ret; + int i; + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_sha1_ctx ctx; + + libssh2_sha1_init(&ctx); + for(i = 0; i < veccount; i++) { + libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + } + libssh2_sha1_final(ctx, hash); + + ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, + signature, signature_len); + if (ret) { + return -1; + } + + return 0; +#endif +} + +/* + * hostkey_method_ssh_rsa_dtor + * + * Shutdown the hostkey + */ +static int +hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); + (void) session; + + _libssh2_rsa_free(rsactx); + + *abstract = NULL; + + return 0; +} + +#ifdef OPENSSL_NO_MD5 +#define MD5_DIGEST_LENGTH 16 +#endif + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = { + "ssh-rsa", + MD5_DIGEST_LENGTH, + hostkey_method_ssh_rsa_init, + hostkey_method_ssh_rsa_initPEM, + hostkey_method_ssh_rsa_initPEMFromMemory, + hostkey_method_ssh_rsa_sig_verify, + hostkey_method_ssh_rsa_signv, + NULL, /* encrypt */ + hostkey_method_ssh_rsa_dtor, +}; +#endif /* LIBSSH2_RSA */ + +#if LIBSSH2_DSA +/* *********** + * ssh-dss * + *********** */ + +static int hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, + void **abstract); + +/* + * hostkey_method_ssh_dss_init + * + * Initialize the server hostkey working area with p/q/g/y set + */ +static int +hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session, + const unsigned char *hostkey_data, + size_t hostkey_data_len, + void **abstract) +{ + libssh2_dsa_ctx *dsactx; + const unsigned char *p, *q, *g, *y, *s; + unsigned long p_len, q_len, g_len, y_len, len; + int ret; + + (void) hostkey_data_len; + + if (*abstract) { + hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } + + s = hostkey_data; + len = _libssh2_ntohu32(s); + s += 4; + if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) { + return -1; + } + s += 7; + + p_len = _libssh2_ntohu32(s); + s += 4; + p = s; + s += p_len; + q_len = _libssh2_ntohu32(s); + s += 4; + q = s; + s += q_len; + g_len = _libssh2_ntohu32(s); + s += 4; + g = s; + s += g_len; + y_len = _libssh2_ntohu32(s); + s += 4; + y = s; + /* s += y_len; */ + + ret = _libssh2_dsa_new(&dsactx, p, p_len, q, q_len, + g, g_len, y, y_len, NULL, 0); + if (ret) { + return -1; + } + + *abstract = dsactx; + + return 0; +} + +/* + * hostkey_method_ssh_dss_initPEM + * + * Load a Private Key from a PEM file + */ +static int +hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_dsa_ctx *dsactx; + int ret; + + if (*abstract) { + hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_dsa_new_private(&dsactx, session, privkeyfile, passphrase); + if (ret) { + return -1; + } + + *abstract = dsactx; + + return 0; +} + +/* + * hostkey_method_ssh_dss_initPEMFromMemory + * + * Load a Private Key from memory + */ +static int +hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session, + const char *privkeyfiledata, + size_t privkeyfiledata_len, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_dsa_ctx *dsactx; + int ret; + + if (*abstract) { + hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_dsa_new_private_frommemory(&dsactx, session, + privkeyfiledata, + privkeyfiledata_len, passphrase); + if (ret) { + return -1; + } + + *abstract = dsactx; + + return 0; +} + +/* + * libssh2_hostkey_method_ssh_dss_sign + * + * Verify signature created by remote + */ +static int +hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session, + const unsigned char *sig, + size_t sig_len, + const unsigned char *m, + size_t m_len, void **abstract) +{ + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); + + /* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */ + sig += 15; + sig_len -= 15; + if (sig_len != 40) { + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid DSS signature length"); + } + return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); +} + +/* + * hostkey_method_ssh_dss_signv + * + * Construct a signature from an array of vectors + */ +static int +hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec datavec[], + void **abstract) +{ + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_sha1_ctx ctx; + int i; + + *signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH); + if (!*signature) { + return -1; + } + + *signature_len = 2 * SHA_DIGEST_LENGTH; + + libssh2_sha1_init(&ctx); + for(i = 0; i < veccount; i++) { + libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + } + libssh2_sha1_final(ctx, hash); + + if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) { + LIBSSH2_FREE(session, *signature); + return -1; + } + + return 0; +} + +/* + * libssh2_hostkey_method_ssh_dss_dtor + * + * Shutdown the hostkey method + */ +static int +hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); + (void) session; + + _libssh2_dsa_free(dsactx); + + *abstract = NULL; + + return 0; +} + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = { + "ssh-dss", + MD5_DIGEST_LENGTH, + hostkey_method_ssh_dss_init, + hostkey_method_ssh_dss_initPEM, + hostkey_method_ssh_dss_initPEMFromMemory, + hostkey_method_ssh_dss_sig_verify, + hostkey_method_ssh_dss_signv, + NULL, /* encrypt */ + hostkey_method_ssh_dss_dtor, +}; +#endif /* LIBSSH2_DSA */ + +static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = { +#if LIBSSH2_RSA + &hostkey_method_ssh_rsa, +#endif /* LIBSSH2_RSA */ +#if LIBSSH2_DSA + &hostkey_method_ssh_dss, +#endif /* LIBSSH2_DSA */ + NULL +}; + +const LIBSSH2_HOSTKEY_METHOD ** +libssh2_hostkey_methods(void) +{ + return hostkey_methods; +} + +/* + * libssh2_hostkey_hash + * + * Returns hash signature + * Returned buffer should NOT be freed + * Length of buffer is determined by hash type + * i.e. MD5 == 16, SHA1 == 20 + */ +LIBSSH2_API const char * +libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type) +{ + switch (hash_type) { +#if LIBSSH2_MD5 + case LIBSSH2_HOSTKEY_HASH_MD5: + return (session->server_hostkey_md5_valid) + ? (char *) session->server_hostkey_md5 + : NULL; + break; +#endif /* LIBSSH2_MD5 */ + case LIBSSH2_HOSTKEY_HASH_SHA1: + return (session->server_hostkey_sha1_valid) + ? (char *) session->server_hostkey_sha1 + : NULL; + break; + default: + return NULL; + } +} + +static int hostkey_type(const unsigned char *hostkey, size_t len) +{ + const unsigned char rsa[] = { + 0, 0, 0, 0x07, 's', 's', 'h', '-', 'r', 's', 'a' + }; + const unsigned char dss[] = { + 0, 0, 0, 0x07, 's', 's', 'h', '-', 'd', 's', 's' + }; + + if (len < 11) + return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; + + if (!memcmp(rsa, hostkey, 11)) + return LIBSSH2_HOSTKEY_TYPE_RSA; + + if (!memcmp(dss, hostkey, 11)) + return LIBSSH2_HOSTKEY_TYPE_DSS; + + return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; +} + +/* + * libssh2_session_hostkey() + * + * Returns the server key and length. + * + */ +LIBSSH2_API const char * +libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type) +{ + if(session->server_hostkey_len) { + if(len) + *len = session->server_hostkey_len; + if (type) + *type = hostkey_type(session->server_hostkey, + session->server_hostkey_len); + return (char *) session->server_hostkey; + } + if(len) + *len = 0; + return NULL; +} + diff --git a/libssh2/src/keepalive.c b/libssh2/src/keepalive.c new file mode 100644 index 000000000..fd749dd29 --- /dev/null +++ b/libssh2/src/keepalive.c @@ -0,0 +1,99 @@ +/* Copyright (C) 2010 Simon Josefsson + * Author: Simon Josefsson + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" +#include "transport.h" /* _libssh2_transport_write */ + +/* Keep-alive stuff. */ + +LIBSSH2_API void +libssh2_keepalive_config (LIBSSH2_SESSION *session, + int want_reply, + unsigned interval) +{ + if (interval == 1) + session->keepalive_interval = 2; + else + session->keepalive_interval = interval; + session->keepalive_want_reply = want_reply ? 1 : 0; +} + +LIBSSH2_API int +libssh2_keepalive_send (LIBSSH2_SESSION *session, + int *seconds_to_next) +{ + time_t now; + + if (!session->keepalive_interval) { + if (seconds_to_next) + *seconds_to_next = 0; + return 0; + } + + now = time (NULL); + + if (session->keepalive_last_sent + session->keepalive_interval <= now) { + /* Format is + "SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */ + unsigned char keepalive_data[] + = "\x50\x00\x00\x00\x15keepalive@libssh2.orgW"; + size_t len = sizeof (keepalive_data) - 1; + int rc; + + keepalive_data[len - 1] = + (unsigned char)session->keepalive_want_reply; + + rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0); + /* Silently ignore PACKET_EAGAIN here: if the write buffer is + already full, sending another keepalive is not useful. */ + if (rc && rc != LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send keepalive message"); + return rc; + } + + session->keepalive_last_sent = now; + if (seconds_to_next) + *seconds_to_next = session->keepalive_interval; + } else if (seconds_to_next) { + *seconds_to_next = (int) (session->keepalive_last_sent - now) + + session->keepalive_interval; + } + + return 0; +} diff --git a/libssh2/src/kex.c b/libssh2/src/kex.c new file mode 100644 index 000000000..65b722f42 --- /dev/null +++ b/libssh2/src/kex.c @@ -0,0 +1,2794 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2010, Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#include "transport.h" +#include "comp.h" +#include "mac.h" + +/* TODO: Switch this to an inline and handle alloc() failures */ +/* Helper macro called from kex_method_diffie_hellman_group1_sha1_key_exchange */ +#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \ + { \ + libssh2_sha1_ctx hash; \ + unsigned long len = 0; \ + if (!(value)) { \ + value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \ + } \ + if (value) \ + while (len < (unsigned long)reqlen) { \ + libssh2_sha1_init(&hash); \ + libssh2_sha1_update(hash, exchange_state->k_value, \ + exchange_state->k_value_len); \ + libssh2_sha1_update(hash, exchange_state->h_sig_comp, \ + SHA_DIGEST_LENGTH); \ + if (len > 0) { \ + libssh2_sha1_update(hash, value, len); \ + } else { \ + libssh2_sha1_update(hash, (version), 1); \ + libssh2_sha1_update(hash, session->session_id, \ + session->session_id_len); \ + } \ + libssh2_sha1_final(hash, (value) + len); \ + len += SHA_DIGEST_LENGTH; \ + } \ + } + + +/* Helper macro called from kex_method_diffie_hellman_group1_sha256_key_exchange */ +#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(value, reqlen, version) \ + { \ + libssh2_sha256_ctx hash; \ + unsigned long len = 0; \ + if (!(value)) { \ + value = LIBSSH2_ALLOC(session, reqlen + SHA256_DIGEST_LENGTH); \ + } \ + if (value) \ + while (len < (unsigned long)reqlen) { \ + libssh2_sha256_init(&hash); \ + libssh2_sha256_update(hash, exchange_state->k_value, \ + exchange_state->k_value_len); \ + libssh2_sha256_update(hash, exchange_state->h_sig_comp, \ + SHA256_DIGEST_LENGTH); \ + if (len > 0) { \ + libssh2_sha256_update(hash, value, len); \ + } else { \ + libssh2_sha256_update(hash, (version), 1); \ + libssh2_sha256_update(hash, session->session_id, \ + session->session_id_len); \ + } \ + libssh2_sha256_final(hash, (value) + len); \ + len += SHA256_DIGEST_LENGTH; \ + } \ + } + + +/* + * diffie_hellman_sha1 + * + * Diffie Hellman Key Exchange, Group Agnostic + */ +static int diffie_hellman_sha1(LIBSSH2_SESSION *session, + _libssh2_bn *g, + _libssh2_bn *p, + int group_order, + unsigned char packet_type_init, + unsigned char packet_type_reply, + unsigned char *midhash, + unsigned long midhash_len, + kmdhgGPshakex_state_t *exchange_state) +{ + int ret = 0; + int rc; + libssh2_sha1_ctx exchange_hash_ctx; + + if (exchange_state->state == libssh2_NB_state_idle) { + /* Setup initial values */ + exchange_state->e_packet = NULL; + exchange_state->s_packet = NULL; + exchange_state->k_value = NULL; + exchange_state->ctx = _libssh2_bn_ctx_new(); + exchange_state->x = _libssh2_bn_init(); /* Random from client */ + exchange_state->e = _libssh2_bn_init(); /* g^x mod p */ + exchange_state->f = _libssh2_bn_init_from_bin(); /* g^(Random from server) mod p */ + exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod p */ + + /* Zero the whole thing out */ + memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); + + /* Generate x and e */ + _libssh2_bn_rand(exchange_state->x, group_order * 8 - 1, 0, -1); + _libssh2_bn_mod_exp(exchange_state->e, g, exchange_state->x, p, + exchange_state->ctx); + + /* Send KEX init */ + /* packet_type(1) + String Length(4) + leading 0(1) */ + exchange_state->e_packet_len = + _libssh2_bn_bytes(exchange_state->e) + 6; + if (_libssh2_bn_bits(exchange_state->e) % 8) { + /* Leading 00 not needed */ + exchange_state->e_packet_len--; + } + + exchange_state->e_packet = + LIBSSH2_ALLOC(session, exchange_state->e_packet_len); + if (!exchange_state->e_packet) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory error"); + goto clean_exit; + } + exchange_state->e_packet[0] = packet_type_init; + _libssh2_htonu32(exchange_state->e_packet + 1, + exchange_state->e_packet_len - 5); + if (_libssh2_bn_bits(exchange_state->e) % 8) { + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 5); + } else { + exchange_state->e_packet[5] = 0; + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 6); + } + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d", + (int) packet_type_init); + exchange_state->state = libssh2_NB_state_created; + } + + if (exchange_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, exchange_state->e_packet, + exchange_state->e_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Unable to send KEX init message"); + goto clean_exit; + } + exchange_state->state = libssh2_NB_state_sent; + } + + if (exchange_state->state == libssh2_NB_state_sent) { + if (session->burn_optimistic_kexinit) { + /* The first KEX packet to come along will be the guess initially + * sent by the server. That guess turned out to be wrong so we + * need to silently ignore it */ + int burn_type; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Waiting for badly guessed KEX packet (to be ignored)"); + burn_type = + _libssh2_packet_burn(session, &exchange_state->burn_state); + if (burn_type == LIBSSH2_ERROR_EAGAIN) { + return burn_type; + } else if (burn_type <= 0) { + /* Failed to receive a packet */ + ret = burn_type; + goto clean_exit; + } + session->burn_optimistic_kexinit = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Burnt packet of type: %02x", + (unsigned int) burn_type); + } + + exchange_state->state = libssh2_NB_state_sent1; + } + + if (exchange_state->state == libssh2_NB_state_sent1) { + /* Wait for KEX reply */ + rc = _libssh2_packet_require(session, packet_type_reply, + &exchange_state->s_packet, + &exchange_state->s_packet_len, 0, NULL, + 0, &exchange_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + if (rc) { + ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting for KEX reply"); + goto clean_exit; + } + + /* Parse KEXDH_REPLY */ + exchange_state->s = exchange_state->s_packet + 1; + + session->server_hostkey_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + + if (session->server_hostkey) + LIBSSH2_FREE(session, session->server_hostkey); + + session->server_hostkey = + LIBSSH2_ALLOC(session, session->server_hostkey_len); + if (!session->server_hostkey) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for a copy " + "of the host key"); + goto clean_exit; + } + memcpy(session->server_hostkey, exchange_state->s, + session->server_hostkey_len); + exchange_state->s += session->server_hostkey_len; + +#if LIBSSH2_MD5 + { + libssh2_md5_ctx fingerprint_ctx; + + if (libssh2_md5_init(&fingerprint_ctx)) { + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5); + session->server_hostkey_md5_valid = TRUE; + } + else { + session->server_hostkey_md5_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[50], *fprint = fingerprint; + int i; + for(i = 0; i < 16; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's MD5 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ +#endif /* ! LIBSSH2_MD5 */ + + { + libssh2_sha1_ctx fingerprint_ctx; + + if (libssh2_sha1_init(&fingerprint_ctx)) { + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1); + session->server_hostkey_sha1_valid = TRUE; + } + else { + session->server_hostkey_sha1_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[64], *fprint = fingerprint; + int i; + + for(i = 0; i < 20; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA1 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ + + if (session->hostkey->init(session, session->server_hostkey, + session->server_hostkey_len, + &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to initialize hostkey importer"); + goto clean_exit; + } + + exchange_state->f_value_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + exchange_state->f_value = exchange_state->s; + exchange_state->s += exchange_state->f_value_len; + _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len, + exchange_state->f_value); + + exchange_state->h_sig_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + exchange_state->h_sig = exchange_state->s; + + /* Compute the shared secret */ + _libssh2_bn_mod_exp(exchange_state->k, exchange_state->f, + exchange_state->x, p, exchange_state->ctx); + exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; + if (_libssh2_bn_bits(exchange_state->k) % 8) { + /* don't need leading 00 */ + exchange_state->k_value_len--; + } + exchange_state->k_value = + LIBSSH2_ALLOC(session, exchange_state->k_value_len); + if (!exchange_state->k_value) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for K"); + goto clean_exit; + } + _libssh2_htonu32(exchange_state->k_value, + exchange_state->k_value_len - 4); + if (_libssh2_bn_bits(exchange_state->k) % 8) { + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); + } else { + exchange_state->k_value[4] = 0; + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); + } + + exchange_state->exchange_hash = (void*)&exchange_hash_ctx; + libssh2_sha1_init(&exchange_hash_ctx); + + if (session->local.banner) { + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->local.banner) - 2); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + (char *) session->local.banner, + strlen((char *) session->local.banner) - 2); + } else { + _libssh2_htonu32(exchange_state->h_sig_comp, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + LIBSSH2_SSH_DEFAULT_BANNER, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + } + + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->remote.banner)); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->remote.banner, + strlen((char *) session->remote.banner)); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->local.kexinit_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->local.kexinit, + session->local.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->remote.kexinit_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->remote.kexinit, + session->remote.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->server_hostkey_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->server_hostkey, + session->server_hostkey_len); + + if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { + /* diffie-hellman-group-exchange hashes additional fields */ +#ifdef LIBSSH2_DH_GEX_NEW + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 4, + LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 8, + LIBSSH2_DH_GEX_MAXGROUP); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 12); +#else + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_OPTGROUP); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); +#endif + } + + if (midhash) { + libssh2_sha1_update(exchange_hash_ctx, midhash, + midhash_len); + } + + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->e_packet + 1, + exchange_state->e_packet_len - 1); + + _libssh2_htonu32(exchange_state->h_sig_comp, + exchange_state->f_value_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->f_value, + exchange_state->f_value_len); + + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->k_value, + exchange_state->k_value_len); + + libssh2_sha1_final(exchange_hash_ctx, + exchange_state->h_sig_comp); + + if (session->hostkey-> + sig_verify(session, exchange_state->h_sig, + exchange_state->h_sig_len, exchange_state->h_sig_comp, + 20, &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, + "Unable to verify hostkey signature"); + goto clean_exit; + } + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message"); + exchange_state->c = SSH_MSG_NEWKEYS; + + exchange_state->state = libssh2_NB_state_sent2; + } + + if (exchange_state->state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message"); + goto clean_exit; + } + + exchange_state->state = libssh2_NB_state_sent3; + } + + if (exchange_state->state == libssh2_NB_state_sent3) { + rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, + &exchange_state->tmp, + &exchange_state->tmp_len, 0, NULL, 0, + &exchange_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS"); + goto clean_exit; + } + /* The first key exchange has been performed, + switch to active crypt/comp/mac mode */ + session->state |= LIBSSH2_STATE_NEWKEYS; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message"); + + /* This will actually end up being just packet_type(1) + for this packet type anyway */ + LIBSSH2_FREE(session, exchange_state->tmp); + + if (!session->session_id) { + session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH); + if (!session->session_id) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for SHA digest"); + goto clean_exit; + } + memcpy(session->session_id, exchange_state->h_sig_comp, + SHA_DIGEST_LENGTH); + session->session_id_len = SHA_DIGEST_LENGTH; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "session_id calculated"); + } + + /* Cleanup any existing cipher */ + if (session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + + /* Calculate IV/Secret/Key for each direction */ + if (session->local.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, + session->local.crypt-> + iv_len, "A"); + if (!iv) { + ret = -1; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, + session->local.crypt-> + secret_len, "C"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if (session->local.crypt-> + init(session, session->local.crypt, iv, &free_iv, secret, + &free_secret, 1, &session->local.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if (free_iv) { + memset(iv, 0, session->local.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if (free_secret) { + memset(secret, 0, session->local.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server IV and Key calculated"); + + if (session->remote.crypt->dtor) { + /* Cleanup any existing cipher */ + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + + if (session->remote.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, + session->remote.crypt-> + iv_len, "B"); + if (!iv) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, + session->remote.crypt-> + secret_len, "D"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if (session->remote.crypt-> + init(session, session->remote.crypt, iv, &free_iv, secret, + &free_secret, 0, &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if (free_iv) { + memset(iv, 0, session->remote.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if (free_secret) { + memset(secret, 0, session->remote.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client IV and Key calculated"); + + if (session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + if (session->local.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, + session->local.mac-> + key_len, "E"); + if (!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->local.mac->init(session, key, &free_key, + &session->local.mac_abstract); + + if (free_key) { + memset(key, 0, session->local.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server HMAC Key calculated"); + + if (session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + if (session->remote.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, + session->remote.mac-> + key_len, "F"); + if (!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->remote.mac->init(session, key, &free_key, + &session->remote.mac_abstract); + + if (free_key) { + memset(key, 0, session->remote.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client HMAC Key calculated"); + + /* Initialize compression for each direction */ + + /* Cleanup any existing compression */ + if (session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + + if (session->local.comp && session->local.comp->init) { + if (session->local.comp->init(session, 1, + &session->local.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server compression initialized"); + + if (session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + + if (session->remote.comp && session->remote.comp->init) { + if (session->remote.comp->init(session, 0, + &session->remote.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client compression initialized"); + + } + + clean_exit: + _libssh2_bn_free(exchange_state->x); + exchange_state->x = NULL; + _libssh2_bn_free(exchange_state->e); + exchange_state->e = NULL; + _libssh2_bn_free(exchange_state->f); + exchange_state->f = NULL; + _libssh2_bn_free(exchange_state->k); + exchange_state->k = NULL; + _libssh2_bn_ctx_free(exchange_state->ctx); + exchange_state->ctx = NULL; + + if (exchange_state->e_packet) { + LIBSSH2_FREE(session, exchange_state->e_packet); + exchange_state->e_packet = NULL; + } + + if (exchange_state->s_packet) { + LIBSSH2_FREE(session, exchange_state->s_packet); + exchange_state->s_packet = NULL; + } + + if (exchange_state->k_value) { + LIBSSH2_FREE(session, exchange_state->k_value); + exchange_state->k_value = NULL; + } + + exchange_state->state = libssh2_NB_state_idle; + + return ret; +} + + +/* + * diffie_hellman_sha256 + * + * Diffie Hellman Key Exchange, Group Agnostic + */ +static int diffie_hellman_sha256(LIBSSH2_SESSION *session, + _libssh2_bn *g, + _libssh2_bn *p, + int group_order, + unsigned char packet_type_init, + unsigned char packet_type_reply, + unsigned char *midhash, + unsigned long midhash_len, + kmdhgGPshakex_state_t *exchange_state) +{ + int ret = 0; + int rc; + libssh2_sha256_ctx exchange_hash_ctx; + + if (exchange_state->state == libssh2_NB_state_idle) { + /* Setup initial values */ + exchange_state->e_packet = NULL; + exchange_state->s_packet = NULL; + exchange_state->k_value = NULL; + exchange_state->ctx = _libssh2_bn_ctx_new(); + exchange_state->x = _libssh2_bn_init(); /* Random from client */ + exchange_state->e = _libssh2_bn_init(); /* g^x mod p */ + exchange_state->f = _libssh2_bn_init_from_bin(); /* g^(Random from server) mod p */ + exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod p */ + + /* Zero the whole thing out */ + memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); + + /* Generate x and e */ + _libssh2_bn_rand(exchange_state->x, group_order * 8 - 1, 0, -1); + _libssh2_bn_mod_exp(exchange_state->e, g, exchange_state->x, p, + exchange_state->ctx); + + /* Send KEX init */ + /* packet_type(1) + String Length(4) + leading 0(1) */ + exchange_state->e_packet_len = + _libssh2_bn_bytes(exchange_state->e) + 6; + if (_libssh2_bn_bits(exchange_state->e) % 8) { + /* Leading 00 not needed */ + exchange_state->e_packet_len--; + } + + exchange_state->e_packet = + LIBSSH2_ALLOC(session, exchange_state->e_packet_len); + if (!exchange_state->e_packet) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory error"); + goto clean_exit; + } + exchange_state->e_packet[0] = packet_type_init; + _libssh2_htonu32(exchange_state->e_packet + 1, + exchange_state->e_packet_len - 5); + if (_libssh2_bn_bits(exchange_state->e) % 8) { + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 5); + } else { + exchange_state->e_packet[5] = 0; + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 6); + } + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d", + (int) packet_type_init); + exchange_state->state = libssh2_NB_state_created; + } + + if (exchange_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, exchange_state->e_packet, + exchange_state->e_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Unable to send KEX init message"); + goto clean_exit; + } + exchange_state->state = libssh2_NB_state_sent; + } + + if (exchange_state->state == libssh2_NB_state_sent) { + if (session->burn_optimistic_kexinit) { + /* The first KEX packet to come along will be the guess initially + * sent by the server. That guess turned out to be wrong so we + * need to silently ignore it */ + int burn_type; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Waiting for badly guessed KEX packet (to be ignored)"); + burn_type = + _libssh2_packet_burn(session, &exchange_state->burn_state); + if (burn_type == LIBSSH2_ERROR_EAGAIN) { + return burn_type; + } else if (burn_type <= 0) { + /* Failed to receive a packet */ + ret = burn_type; + goto clean_exit; + } + session->burn_optimistic_kexinit = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Burnt packet of type: %02x", + (unsigned int) burn_type); + } + + exchange_state->state = libssh2_NB_state_sent1; + } + + if (exchange_state->state == libssh2_NB_state_sent1) { + /* Wait for KEX reply */ + rc = _libssh2_packet_require(session, packet_type_reply, + &exchange_state->s_packet, + &exchange_state->s_packet_len, 0, NULL, + 0, &exchange_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + if (rc) { + ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting for KEX reply"); + goto clean_exit; + } + + /* Parse KEXDH_REPLY */ + exchange_state->s = exchange_state->s_packet + 1; + + session->server_hostkey_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + + if (session->server_hostkey) + LIBSSH2_FREE(session, session->server_hostkey); + + session->server_hostkey = + LIBSSH2_ALLOC(session, session->server_hostkey_len); + if (!session->server_hostkey) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for a copy " + "of the host key"); + goto clean_exit; + } + memcpy(session->server_hostkey, exchange_state->s, + session->server_hostkey_len); + exchange_state->s += session->server_hostkey_len; + +#if LIBSSH2_MD5 + { + libssh2_md5_ctx fingerprint_ctx; + + if (libssh2_md5_init(&fingerprint_ctx)) { + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5); + session->server_hostkey_md5_valid = TRUE; + } + else { + session->server_hostkey_md5_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[50], *fprint = fingerprint; + int i; + for(i = 0; i < 16; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's MD5 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ +#endif /* ! LIBSSH2_MD5 */ + + { + libssh2_sha1_ctx fingerprint_ctx; + + if (libssh2_sha1_init(&fingerprint_ctx)) { + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1); + session->server_hostkey_sha1_valid = TRUE; + } + else { + session->server_hostkey_sha1_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[64], *fprint = fingerprint; + int i; + + for(i = 0; i < 20; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA1 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ + + if (session->hostkey->init(session, session->server_hostkey, + session->server_hostkey_len, + &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to initialize hostkey importer"); + goto clean_exit; + } + + exchange_state->f_value_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + exchange_state->f_value = exchange_state->s; + exchange_state->s += exchange_state->f_value_len; + _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len, + exchange_state->f_value); + + exchange_state->h_sig_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + exchange_state->h_sig = exchange_state->s; + + /* Compute the shared secret */ + _libssh2_bn_mod_exp(exchange_state->k, exchange_state->f, + exchange_state->x, p, exchange_state->ctx); + exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; + if (_libssh2_bn_bits(exchange_state->k) % 8) { + /* don't need leading 00 */ + exchange_state->k_value_len--; + } + exchange_state->k_value = + LIBSSH2_ALLOC(session, exchange_state->k_value_len); + if (!exchange_state->k_value) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for K"); + goto clean_exit; + } + _libssh2_htonu32(exchange_state->k_value, + exchange_state->k_value_len - 4); + if (_libssh2_bn_bits(exchange_state->k) % 8) { + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); + } else { + exchange_state->k_value[4] = 0; + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); + } + + exchange_state->exchange_hash = (void*)&exchange_hash_ctx; + libssh2_sha256_init(&exchange_hash_ctx); + + if (session->local.banner) { + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->local.banner) - 2); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + (char *) session->local.banner, + strlen((char *) session->local.banner) - 2); + } else { + _libssh2_htonu32(exchange_state->h_sig_comp, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + LIBSSH2_SSH_DEFAULT_BANNER, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + } + + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->remote.banner)); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->remote.banner, + strlen((char *) session->remote.banner)); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->local.kexinit_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->local.kexinit, + session->local.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->remote.kexinit_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->remote.kexinit, + session->remote.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->server_hostkey_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->server_hostkey, + session->server_hostkey_len); + + if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { + /* diffie-hellman-group-exchange hashes additional fields */ +#ifdef LIBSSH2_DH_GEX_NEW + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 4, + LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 8, + LIBSSH2_DH_GEX_MAXGROUP); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 12); +#else + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_OPTGROUP); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); +#endif + } + + if (midhash) { + libssh2_sha256_update(exchange_hash_ctx, midhash, + midhash_len); + } + + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->e_packet + 1, + exchange_state->e_packet_len - 1); + + _libssh2_htonu32(exchange_state->h_sig_comp, + exchange_state->f_value_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->f_value, + exchange_state->f_value_len); + + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->k_value, + exchange_state->k_value_len); + + libssh2_sha256_final(exchange_hash_ctx, + exchange_state->h_sig_comp); + + if (session->hostkey-> + sig_verify(session, exchange_state->h_sig, + exchange_state->h_sig_len, exchange_state->h_sig_comp, + SHA256_DIGEST_LENGTH, &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, + "Unable to verify hostkey signature"); + goto clean_exit; + } + + + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message"); + exchange_state->c = SSH_MSG_NEWKEYS; + + exchange_state->state = libssh2_NB_state_sent2; + } + + if (exchange_state->state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message"); + goto clean_exit; + } + + exchange_state->state = libssh2_NB_state_sent3; + } + + if (exchange_state->state == libssh2_NB_state_sent3) { + rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, + &exchange_state->tmp, + &exchange_state->tmp_len, 0, NULL, 0, + &exchange_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS"); + goto clean_exit; + } + /* The first key exchange has been performed, + switch to active crypt/comp/mac mode */ + session->state |= LIBSSH2_STATE_NEWKEYS; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message"); + + /* This will actually end up being just packet_type(1) + for this packet type anyway */ + LIBSSH2_FREE(session, exchange_state->tmp); + + if (!session->session_id) { + session->session_id = LIBSSH2_ALLOC(session, SHA256_DIGEST_LENGTH); + if (!session->session_id) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for SHA digest"); + goto clean_exit; + } + memcpy(session->session_id, exchange_state->h_sig_comp, + SHA256_DIGEST_LENGTH); + session->session_id_len = SHA256_DIGEST_LENGTH; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "session_id calculated"); + } + + /* Cleanup any existing cipher */ + if (session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + + /* Calculate IV/Secret/Key for each direction */ + if (session->local.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(iv, + session->local.crypt-> + iv_len, "A"); + if (!iv) { + ret = -1; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(secret, + session->local.crypt-> + secret_len, "C"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if (session->local.crypt-> + init(session, session->local.crypt, iv, &free_iv, secret, + &free_secret, 1, &session->local.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if (free_iv) { + memset(iv, 0, session->local.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if (free_secret) { + memset(secret, 0, session->local.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server IV and Key calculated"); + + if (session->remote.crypt->dtor) { + /* Cleanup any existing cipher */ + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + + if (session->remote.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(iv, + session->remote.crypt-> + iv_len, "B"); + if (!iv) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(secret, + session->remote.crypt-> + secret_len, "D"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if (session->remote.crypt-> + init(session, session->remote.crypt, iv, &free_iv, secret, + &free_secret, 0, &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if (free_iv) { + memset(iv, 0, session->remote.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if (free_secret) { + memset(secret, 0, session->remote.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client IV and Key calculated"); + + if (session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + if (session->local.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(key, + session->local.mac-> + key_len, "E"); + if (!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->local.mac->init(session, key, &free_key, + &session->local.mac_abstract); + + if (free_key) { + memset(key, 0, session->local.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server HMAC Key calculated"); + + if (session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + if (session->remote.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(key, + session->remote.mac-> + key_len, "F"); + if (!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->remote.mac->init(session, key, &free_key, + &session->remote.mac_abstract); + + if (free_key) { + memset(key, 0, session->remote.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client HMAC Key calculated"); + + /* Initialize compression for each direction */ + + /* Cleanup any existing compression */ + if (session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + + if (session->local.comp && session->local.comp->init) { + if (session->local.comp->init(session, 1, + &session->local.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server compression initialized"); + + if (session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + + if (session->remote.comp && session->remote.comp->init) { + if (session->remote.comp->init(session, 0, + &session->remote.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client compression initialized"); + + } + + clean_exit: + _libssh2_bn_free(exchange_state->x); + exchange_state->x = NULL; + _libssh2_bn_free(exchange_state->e); + exchange_state->e = NULL; + _libssh2_bn_free(exchange_state->f); + exchange_state->f = NULL; + _libssh2_bn_free(exchange_state->k); + exchange_state->k = NULL; + _libssh2_bn_ctx_free(exchange_state->ctx); + exchange_state->ctx = NULL; + + if (exchange_state->e_packet) { + LIBSSH2_FREE(session, exchange_state->e_packet); + exchange_state->e_packet = NULL; + } + + if (exchange_state->s_packet) { + LIBSSH2_FREE(session, exchange_state->s_packet); + exchange_state->s_packet = NULL; + } + + if (exchange_state->k_value) { + LIBSSH2_FREE(session, exchange_state->k_value); + exchange_state->k_value = NULL; + } + + exchange_state->state = libssh2_NB_state_idle; + + return ret; +} + + + +/* kex_method_diffie_hellman_group1_sha1_key_exchange + * Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1 + */ +static int +kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session, + key_exchange_state_low_t + * key_state) +{ + static const unsigned char p_value[128] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + + int ret; + + if (key_state->state == libssh2_NB_state_idle) { + /* g == 2 */ + key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */ + key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + + /* Initialize P and G */ + _libssh2_bn_set_word(key_state->g, 2); + _libssh2_bn_from_bin(key_state->p, 128, p_value); + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group1 Key Exchange"); + + key_state->state = libssh2_NB_state_created; + } + ret = diffie_hellman_sha1(session, key_state->g, key_state->p, 128, + SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, + NULL, 0, &key_state->exchange_state); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + key_state->state = libssh2_NB_state_idle; + + return ret; +} + + + +/* kex_method_diffie_hellman_group14_sha1_key_exchange + * Diffie-Hellman Group14 Key Exchange using SHA1 + */ +static int +kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session, + key_exchange_state_low_t + * key_state) +{ + static const unsigned char p_value[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + int ret; + + if (key_state->state == libssh2_NB_state_idle) { + key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */ + key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + + /* g == 2 */ + /* Initialize P and G */ + _libssh2_bn_set_word(key_state->g, 2); + _libssh2_bn_from_bin(key_state->p, 256, p_value); + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group14 Key Exchange"); + + key_state->state = libssh2_NB_state_created; + } + ret = diffie_hellman_sha1(session, key_state->g, key_state->p, + 256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, + NULL, 0, &key_state->exchange_state); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + key_state->state = libssh2_NB_state_idle; + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + + return ret; +} + + + +/* kex_method_diffie_hellman_group_exchange_sha1_key_exchange + * Diffie-Hellman Group Exchange Key Exchange using SHA1 + * Negotiates random(ish) group for secret derivation + */ +static int +kex_method_diffie_hellman_group_exchange_sha1_key_exchange +(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) +{ + unsigned long p_len, g_len; + int ret = 0; + int rc; + + if (key_state->state == libssh2_NB_state_idle) { + key_state->p = _libssh2_bn_init_from_bin(); + key_state->g = _libssh2_bn_init_from_bin(); + /* Ask for a P and G pair */ +#ifdef LIBSSH2_DH_GEX_NEW + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP); + key_state->request_len = 13; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange (New Method)"); +#else + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP); + key_state->request_len = 5; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange (Old Method)"); +#endif + + key_state->state = libssh2_NB_state_created; + } + + if (key_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, key_state->request, + key_state->request_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Unable to send Group Exchange Request"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent; + } + + if (key_state->state == libssh2_NB_state_sent) { + rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, + &key_state->data, &key_state->data_len, + 0, NULL, 0, &key_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Timeout waiting for GEX_GROUP reply"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if (key_state->state == libssh2_NB_state_sent1) { + unsigned char *s = key_state->data + 1; + p_len = _libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->p, p_len, s); + s += p_len; + + g_len = _libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->g, g_len, s); + + ret = diffie_hellman_sha1(session, key_state->g, key_state->p, p_len, + SSH_MSG_KEX_DH_GEX_INIT, + SSH_MSG_KEX_DH_GEX_REPLY, + key_state->data + 1, + key_state->data_len - 1, + &key_state->exchange_state); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + LIBSSH2_FREE(session, key_state->data); + } + + dh_gex_clean_exit: + key_state->state = libssh2_NB_state_idle; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + + return ret; +} + + + +/* kex_method_diffie_hellman_group_exchange_sha256_key_exchange + * Diffie-Hellman Group Exchange Key Exchange using SHA256 + * Negotiates random(ish) group for secret derivation + */ +static int +kex_method_diffie_hellman_group_exchange_sha256_key_exchange +(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) +{ + unsigned long p_len, g_len; + int ret = 0; + int rc; + + if (key_state->state == libssh2_NB_state_idle) { + key_state->p = _libssh2_bn_init(); + key_state->g = _libssh2_bn_init(); + /* Ask for a P and G pair */ +#ifdef LIBSSH2_DH_GEX_NEW + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP); + key_state->request_len = 13; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange (New Method SHA256)"); +#else + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP); + key_state->request_len = 5; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange (Old Method SHA256)"); +#endif + + key_state->state = libssh2_NB_state_created; + } + + if (key_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, key_state->request, + key_state->request_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Unable to send Group Exchange Request SHA256"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent; + } + + if (key_state->state == libssh2_NB_state_sent) { + rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, + &key_state->data, &key_state->data_len, + 0, NULL, 0, &key_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Timeout waiting for GEX_GROUP reply SHA256"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if (key_state->state == libssh2_NB_state_sent1) { + unsigned char *s = key_state->data + 1; + p_len = _libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->p, p_len, s); + s += p_len; + + g_len = _libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->g, g_len, s); + + ret = diffie_hellman_sha256(session, key_state->g, key_state->p, p_len, + SSH_MSG_KEX_DH_GEX_INIT, + SSH_MSG_KEX_DH_GEX_REPLY, + key_state->data + 1, + key_state->data_len - 1, + &key_state->exchange_state); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + LIBSSH2_FREE(session, key_state->data); + } + + dh_gex_clean_exit: + key_state->state = libssh2_NB_state_idle; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + + return ret; +} + + +#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001 +#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002 + +static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group1_sha1 = { + "diffie-hellman-group1-sha1", + kex_method_diffie_hellman_group1_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha1 = { + "diffie-hellman-group14-sha1", + kex_method_diffie_hellman_group14_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD +kex_method_diffie_helman_group_exchange_sha1 = { + "diffie-hellman-group-exchange-sha1", + kex_method_diffie_hellman_group_exchange_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD +kex_method_diffie_helman_group_exchange_sha256 = { + "diffie-hellman-group-exchange-sha256", + kex_method_diffie_hellman_group_exchange_sha256_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = { + &kex_method_diffie_helman_group_exchange_sha256, + &kex_method_diffie_helman_group_exchange_sha1, + &kex_method_diffie_helman_group14_sha1, + &kex_method_diffie_helman_group1_sha1, + NULL +}; + +typedef struct _LIBSSH2_COMMON_METHOD +{ + const char *name; +} LIBSSH2_COMMON_METHOD; + +/* kex_method_strlen + * Calculate the length of a particular method list's resulting string + * Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1 (because the last coma isn't used) + * Another sign of bad coding practices gone mad. Pretend you don't see this. + */ +static size_t +kex_method_strlen(LIBSSH2_COMMON_METHOD ** method) +{ + size_t len = 0; + + if (!method || !*method) { + return 0; + } + + while (*method && (*method)->name) { + len += strlen((*method)->name) + 1; + method++; + } + + return len - 1; +} + + + +/* kex_method_list + * Generate formatted preference list in buf + */ +static size_t +kex_method_list(unsigned char *buf, size_t list_strlen, + LIBSSH2_COMMON_METHOD ** method) +{ + _libssh2_htonu32(buf, list_strlen); + buf += 4; + + if (!method || !*method) { + return 4; + } + + while (*method && (*method)->name) { + int mlen = strlen((*method)->name); + memcpy(buf, (*method)->name, mlen); + buf += mlen; + *(buf++) = ','; + method++; + } + + return list_strlen + 4; +} + + + +#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) \ + ((prefvar) ? strlen(prefvar) : \ + kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar))) + +#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \ + if (prefvar) { \ + _libssh2_htonu32((buf), (prefvarlen)); \ + buf += 4; \ + memcpy((buf), (prefvar), (prefvarlen)); \ + buf += (prefvarlen); \ + } else { \ + buf += kex_method_list((buf), (prefvarlen), \ + (LIBSSH2_COMMON_METHOD**)(defaultvar)); \ + } + +/* kexinit + * Send SSH_MSG_KEXINIT packet + */ +static int kexinit(LIBSSH2_SESSION * session) +{ + /* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) + + reserved(4) + length longs(40) */ + size_t data_len = 62; + size_t kex_len, hostkey_len = 0; + size_t crypt_cs_len, crypt_sc_len; + size_t comp_cs_len, comp_sc_len; + size_t mac_cs_len, mac_sc_len; + size_t lang_cs_len, lang_sc_len; + unsigned char *data, *s; + int rc; + + if (session->kexinit_state == libssh2_NB_state_idle) { + kex_len = + LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods); + hostkey_len = + LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs, + libssh2_hostkey_methods()); + crypt_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs, + libssh2_crypt_methods()); + crypt_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs, + libssh2_crypt_methods()); + mac_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs, + _libssh2_mac_methods()); + mac_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs, + _libssh2_mac_methods()); + comp_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs, + _libssh2_comp_methods(session)); + comp_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs, + _libssh2_comp_methods(session)); + lang_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL); + lang_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL); + + data_len += kex_len + hostkey_len + crypt_cs_len + crypt_sc_len + + comp_cs_len + comp_sc_len + mac_cs_len + mac_sc_len + + lang_cs_len + lang_sc_len; + + s = data = LIBSSH2_ALLOC(session, data_len); + if (!data) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory"); + } + + *(s++) = SSH_MSG_KEXINIT; + + _libssh2_random(s, 16); + s += 16; + + /* Ennumerating through these lists twice is probably (certainly?) + inefficient from a CPU standpoint, but it saves multiple + malloc/realloc calls */ + LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs, + libssh2_kex_methods); + LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs, + libssh2_hostkey_methods()); + LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs, + libssh2_crypt_methods()); + LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs, + libssh2_crypt_methods()); + LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs, + _libssh2_mac_methods()); + LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs, + _libssh2_mac_methods()); + LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs, + _libssh2_comp_methods(session)); + LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs, + _libssh2_comp_methods(session)); + LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs, + NULL); + LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs, + NULL); + + /* No optimistic KEX packet follows */ + /* Deal with optimistic packets + * session->flags |= KEXINIT_OPTIMISTIC + * session->flags |= KEXINIT_METHODSMATCH + */ + *(s++) = 0; + + /* Reserved == 0 */ + _libssh2_htonu32(s, 0); + +#ifdef LIBSSH2DEBUG + { + /* Funnily enough, they'll all "appear" to be '\0' terminated */ + unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */ + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent KEX: %s", p); + p += kex_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent HOSTKEY: %s", p); + p += hostkey_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_CS: %s", p); + p += crypt_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_SC: %s", p); + p += crypt_sc_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_CS: %s", p); + p += mac_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_SC: %s", p); + p += mac_sc_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_CS: %s", p); + p += comp_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_SC: %s", p); + p += comp_sc_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_CS: %s", p); + p += lang_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_SC: %s", p); + p += lang_sc_len + 4; + } +#endif /* LIBSSH2DEBUG */ + + session->kexinit_state = libssh2_NB_state_created; + } else { + data = session->kexinit_data; + data_len = session->kexinit_data_len; + /* zap the variables to ensure there is NOT a double free later */ + session->kexinit_data = NULL; + session->kexinit_data_len = 0; + } + + rc = _libssh2_transport_send(session, data, data_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + session->kexinit_data = data; + session->kexinit_data_len = data_len; + return rc; + } + else if (rc) { + LIBSSH2_FREE(session, data); + session->kexinit_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send KEXINIT packet to remote host"); + + } + + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + + session->local.kexinit = data; + session->local.kexinit_len = data_len; + + session->kexinit_state = libssh2_NB_state_idle; + + return 0; +} + +/* kex_agree_instr + * Kex specific variant of strstr() + * Needle must be preceed by BOL or ',', and followed by ',' or EOL + */ +static unsigned char * +kex_agree_instr(unsigned char *haystack, unsigned long haystack_len, + const unsigned char *needle, unsigned long needle_len) +{ + unsigned char *s; + + /* Haystack too short to bother trying */ + if (haystack_len < needle_len) { + return NULL; + } + + /* Needle at start of haystack */ + if ((strncmp((char *) haystack, (char *) needle, needle_len) == 0) && + (needle_len == haystack_len || haystack[needle_len] == ',')) { + return haystack; + } + + s = haystack; + /* Search until we run out of comas or we run out of haystack, + whichever comes first */ + while ((s = (unsigned char *) strchr((char *) s, ',')) + && ((haystack_len - (s - haystack)) > needle_len)) { + s++; + /* Needle at X position */ + if ((strncmp((char *) s, (char *) needle, needle_len) == 0) && + (((s - haystack) + needle_len) == haystack_len + || s[needle_len] == ',')) { + return s; + } + } + + return NULL; +} + + + +/* kex_get_method_by_name + */ +static const LIBSSH2_COMMON_METHOD * +kex_get_method_by_name(const char *name, size_t name_len, + const LIBSSH2_COMMON_METHOD ** methodlist) +{ + while (*methodlist) { + if ((strlen((*methodlist)->name) == name_len) && + (strncmp((*methodlist)->name, name, name_len) == 0)) { + return *methodlist; + } + methodlist++; + } + return NULL; +} + + + +/* kex_agree_hostkey + * Agree on a Hostkey which works with this kex + */ +static int kex_agree_hostkey(LIBSSH2_SESSION * session, + unsigned long kex_flags, + unsigned char *hostkey, unsigned long hostkey_len) +{ + const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods(); + unsigned char *s; + + if (session->hostkey_prefs) { + s = (unsigned char *) session->hostkey_prefs; + + while (s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + if (kex_agree_instr(hostkey, hostkey_len, s, method_len)) { + const LIBSSH2_HOSTKEY_METHOD *method = + (const LIBSSH2_HOSTKEY_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + hostkeyp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + /* So far so good, but does it suit our purposes? (Encrypting + vs Signing) */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == + 0) || (method->encrypt)) { + /* Either this hostkey can do encryption or this kex just + doesn't require it */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) + == 0) || (method->sig_verify)) { + /* Either this hostkey can do signing or this kex just + doesn't require it */ + session->hostkey = method; + return 0; + } + } + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (hostkeyp && (*hostkeyp) && (*hostkeyp)->name) { + s = kex_agree_instr(hostkey, hostkey_len, + (unsigned char *) (*hostkeyp)->name, + strlen((*hostkeyp)->name)); + if (s) { + /* So far so good, but does it suit our purposes? (Encrypting vs + Signing) */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) || + ((*hostkeyp)->encrypt)) { + /* Either this hostkey can do encryption or this kex just + doesn't require it */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) == + 0) || ((*hostkeyp)->sig_verify)) { + /* Either this hostkey can do signing or this kex just + doesn't require it */ + session->hostkey = *hostkeyp; + return 0; + } + } + } + hostkeyp++; + } + + return -1; +} + + + +/* kex_agree_kex_hostkey + * Agree on a Key Exchange method and a hostkey encoding type + */ +static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex, + unsigned long kex_len, unsigned char *hostkey, + unsigned long hostkey_len) +{ + const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods; + unsigned char *s; + + if (session->kex_prefs) { + s = (unsigned char *) session->kex_prefs; + + while (s && *s) { + unsigned char *q, *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + if ((q = kex_agree_instr(kex, kex_len, s, method_len))) { + const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + kexp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + /* We've agreed on a key exchange method, + * Can we agree on a hostkey that works with this kex? + */ + if (kex_agree_hostkey(session, method->flags, hostkey, + hostkey_len) == 0) { + session->kex = method; + if (session->burn_optimistic_kexinit && (kex == q)) { + /* Server sent an optimistic packet, + * and client agrees with preference + * cancel burning the first KEX_INIT packet that comes in */ + session->burn_optimistic_kexinit = 0; + } + return 0; + } + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (*kexp && (*kexp)->name) { + s = kex_agree_instr(kex, kex_len, + (unsigned char *) (*kexp)->name, + strlen((*kexp)->name)); + if (s) { + /* We've agreed on a key exchange method, + * Can we agree on a hostkey that works with this kex? + */ + if (kex_agree_hostkey(session, (*kexp)->flags, hostkey, + hostkey_len) == 0) { + session->kex = *kexp; + if (session->burn_optimistic_kexinit && (kex == s)) { + /* Server sent an optimistic packet, + * and client agrees with preference + * cancel burning the first KEX_INIT packet that comes in */ + session->burn_optimistic_kexinit = 0; + } + return 0; + } + } + kexp++; + } + return -1; +} + + + +/* kex_agree_crypt + * Agree on a cipher algo + */ +static int kex_agree_crypt(LIBSSH2_SESSION * session, + libssh2_endpoint_data *endpoint, + unsigned char *crypt, + unsigned long crypt_len) +{ + const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods(); + unsigned char *s; + + (void) session; + + if (endpoint->crypt_prefs) { + s = (unsigned char *) endpoint->crypt_prefs; + + while (s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + + if (kex_agree_instr(crypt, crypt_len, s, method_len)) { + const LIBSSH2_CRYPT_METHOD *method = + (const LIBSSH2_CRYPT_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + cryptp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + endpoint->crypt = method; + return 0; + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (*cryptp && (*cryptp)->name) { + s = kex_agree_instr(crypt, crypt_len, + (unsigned char *) (*cryptp)->name, + strlen((*cryptp)->name)); + if (s) { + endpoint->crypt = *cryptp; + return 0; + } + cryptp++; + } + + return -1; +} + + + +/* kex_agree_mac + * Agree on a message authentication hash + */ +static int kex_agree_mac(LIBSSH2_SESSION * session, + libssh2_endpoint_data * endpoint, unsigned char *mac, + unsigned long mac_len) +{ + const LIBSSH2_MAC_METHOD **macp = _libssh2_mac_methods(); + unsigned char *s; + (void) session; + + if (endpoint->mac_prefs) { + s = (unsigned char *) endpoint->mac_prefs; + + while (s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + + if (kex_agree_instr(mac, mac_len, s, method_len)) { + const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + macp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + endpoint->mac = method; + return 0; + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (*macp && (*macp)->name) { + s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name, + strlen((*macp)->name)); + if (s) { + endpoint->mac = *macp; + return 0; + } + macp++; + } + + return -1; +} + + + +/* kex_agree_comp + * Agree on a compression scheme + */ +static int kex_agree_comp(LIBSSH2_SESSION *session, + libssh2_endpoint_data *endpoint, unsigned char *comp, + unsigned long comp_len) +{ + const LIBSSH2_COMP_METHOD **compp = _libssh2_comp_methods(session); + unsigned char *s; + (void) session; + + if (endpoint->comp_prefs) { + s = (unsigned char *) endpoint->comp_prefs; + + while (s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + + if (kex_agree_instr(comp, comp_len, s, method_len)) { + const LIBSSH2_COMP_METHOD *method = + (const LIBSSH2_COMP_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + compp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + endpoint->comp = method; + return 0; + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (*compp && (*compp)->name) { + s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name, + strlen((*compp)->name)); + if (s) { + endpoint->comp = *compp; + return 0; + } + compp++; + } + + return -1; +} + + + +/* TODO: When in server mode we need to turn this logic on its head + * The Client gets to make the final call on "agreed methods" + */ + +/* + * kex_string_pair() extracts a string from the packet and makes sure it fits + * within the given packet. + */ +static int kex_string_pair(unsigned char **sp, /* parsing position */ + unsigned char *data, /* start pointer to packet */ + size_t data_len, /* size of total packet */ + size_t *lenp, /* length of the string */ + unsigned char **strp) /* pointer to string start */ +{ + unsigned char *s = *sp; + *lenp = _libssh2_ntohu32(s); + + /* the length of the string must fit within the current pointer and the + end of the packet */ + if (*lenp > (data_len - (s - data) -4)) + return 1; + *strp = s + 4; + s += 4 + *lenp; + + *sp = s; + return 0; +} + +/* kex_agree_methods + * Decide which specific method to use of the methods offered by each party + */ +static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data, + unsigned data_len) +{ + unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc, + *mac_cs, *mac_sc; + size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len; + size_t comp_sc_len, mac_cs_len, mac_sc_len; + unsigned char *s = data; + + /* Skip packet_type, we know it already */ + s++; + + /* Skip cookie, don't worry, it's preserved in the kexinit field */ + s += 16; + + /* Locate each string */ + if(kex_string_pair(&s, data, data_len, &kex_len, &kex)) + return -1; + if(kex_string_pair(&s, data, data_len, &hostkey_len, &hostkey)) + return -1; + if(kex_string_pair(&s, data, data_len, &crypt_cs_len, &crypt_cs)) + return -1; + if(kex_string_pair(&s, data, data_len, &crypt_sc_len, &crypt_sc)) + return -1; + if(kex_string_pair(&s, data, data_len, &mac_cs_len, &mac_cs)) + return -1; + if(kex_string_pair(&s, data, data_len, &mac_sc_len, &mac_sc)) + return -1; + if(kex_string_pair(&s, data, data_len, &comp_cs_len, &comp_cs)) + return -1; + if(kex_string_pair(&s, data, data_len, &comp_sc_len, &comp_sc)) + return -1; + + /* If the server sent an optimistic packet, assume that it guessed wrong. + * If the guess is determined to be right (by kex_agree_kex_hostkey) + * This flag will be reset to zero so that it's not ignored */ + session->burn_optimistic_kexinit = *(s++); + /* Next uint32 in packet is all zeros (reserved) */ + + if (data_len < (unsigned) (s - data)) + return -1; /* short packet */ + + if (kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) { + return -1; + } + + if (kex_agree_crypt(session, &session->local, crypt_cs, crypt_cs_len) + || kex_agree_crypt(session, &session->remote, crypt_sc, crypt_sc_len)) { + return -1; + } + + if (kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) || + kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) { + return -1; + } + + if (kex_agree_comp(session, &session->local, comp_cs, comp_cs_len) || + kex_agree_comp(session, &session->remote, comp_sc, comp_sc_len)) { + return -1; + } + +#if 0 + if (libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len) + || libssh2_kex_agree_lang(session, &session->remote, lang_sc, + lang_sc_len)) { + return -1; + } +#endif + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on KEX method: %s", + session->kex->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on HOSTKEY method: %s", + session->hostkey->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_CS method: %s", + session->local.crypt->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_SC method: %s", + session->remote.crypt->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_CS method: %s", + session->local.mac->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_SC method: %s", + session->remote.mac->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_CS method: %s", + session->local.comp->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_SC method: %s", + session->remote.comp->name); + + return 0; +} + + + +/* _libssh2_kex_exchange + * Exchange keys + * Returns 0 on success, non-zero on failure + * + * Returns some errors without _libssh2_error() + */ +int +_libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + key_exchange_state_t * key_state) +{ + int rc = 0; + int retcode; + + session->state |= LIBSSH2_STATE_KEX_ACTIVE; + + if (key_state->state == libssh2_NB_state_idle) { + /* Prevent loop in packet_add() */ + session->state |= LIBSSH2_STATE_EXCHANGING_KEYS; + + if (reexchange) { + session->kex = NULL; + + if (session->hostkey && session->hostkey->dtor) { + session->hostkey->dtor(session, + &session->server_hostkey_abstract); + } + session->hostkey = NULL; + } + + key_state->state = libssh2_NB_state_created; + } + + if (!session->kex || !session->hostkey) { + if (key_state->state == libssh2_NB_state_created) { + /* Preserve in case of failure */ + key_state->oldlocal = session->local.kexinit; + key_state->oldlocal_len = session->local.kexinit_len; + + session->local.kexinit = NULL; + + key_state->state = libssh2_NB_state_sent; + } + + if (key_state->state == libssh2_NB_state_sent) { + retcode = kexinit(session); + if (retcode == LIBSSH2_ERROR_EAGAIN) { + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + return retcode; + } else if (retcode) { + session->local.kexinit = key_state->oldlocal; + session->local.kexinit_len = key_state->oldlocal_len; + key_state->state = libssh2_NB_state_idle; + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + return -1; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if (key_state->state == libssh2_NB_state_sent1) { + retcode = + _libssh2_packet_require(session, SSH_MSG_KEXINIT, + &key_state->data, + &key_state->data_len, 0, NULL, 0, + &key_state->req_state); + if (retcode == LIBSSH2_ERROR_EAGAIN) { + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + return retcode; + } + else if (retcode) { + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + session->local.kexinit = key_state->oldlocal; + session->local.kexinit_len = key_state->oldlocal_len; + key_state->state = libssh2_NB_state_idle; + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + return -1; + } + + if (session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + } + session->remote.kexinit = key_state->data; + session->remote.kexinit_len = key_state->data_len; + + if (kex_agree_methods(session, key_state->data, + key_state->data_len)) + rc = LIBSSH2_ERROR_KEX_FAILURE; + + key_state->state = libssh2_NB_state_sent2; + } + } else { + key_state->state = libssh2_NB_state_sent2; + } + + if (rc == 0 && session->kex) { + if (key_state->state == libssh2_NB_state_sent2) { + retcode = session->kex->exchange_keys(session, + &key_state->key_state_low); + if (retcode == LIBSSH2_ERROR_EAGAIN) { + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + return retcode; + } else if (retcode) { + rc = _libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, + "Unrecoverable error exchanging keys"); + } + } + } + + /* Done with kexinit buffers */ + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + session->local.kexinit = NULL; + } + if (session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + session->remote.kexinit = NULL; + } + + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + + key_state->state = libssh2_NB_state_idle; + + return rc; +} + + + +/* libssh2_session_method_pref + * Set preferred method + */ +LIBSSH2_API int +libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type, + const char *prefs) +{ + char **prefvar, *s, *newprefs; + int prefs_len = strlen(prefs); + const LIBSSH2_COMMON_METHOD **mlist; + + switch (method_type) { + case LIBSSH2_METHOD_KEX: + prefvar = &session->kex_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods; + break; + + case LIBSSH2_METHOD_HOSTKEY: + prefvar = &session->hostkey_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods(); + break; + + case LIBSSH2_METHOD_CRYPT_CS: + prefvar = &session->local.crypt_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods(); + break; + + case LIBSSH2_METHOD_CRYPT_SC: + prefvar = &session->remote.crypt_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods(); + break; + + case LIBSSH2_METHOD_MAC_CS: + prefvar = &session->local.mac_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods(); + break; + + case LIBSSH2_METHOD_MAC_SC: + prefvar = &session->remote.mac_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods(); + break; + + case LIBSSH2_METHOD_COMP_CS: + prefvar = &session->local.comp_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) + _libssh2_comp_methods(session); + break; + + case LIBSSH2_METHOD_COMP_SC: + prefvar = &session->remote.comp_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) + _libssh2_comp_methods(session); + break; + + case LIBSSH2_METHOD_LANG_CS: + prefvar = &session->local.lang_prefs; + mlist = NULL; + break; + + case LIBSSH2_METHOD_LANG_SC: + prefvar = &session->remote.lang_prefs; + mlist = NULL; + break; + + default: + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "Invalid parameter specified for method_type"); + } + + s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1); + if (!newprefs) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Error allocated space for method preferences"); + } + memcpy(s, prefs, prefs_len + 1); + + while (s && *s && mlist) { + char *p = strchr(s, ','); + int method_len = p ? (p - s) : (int) strlen(s); + + if (!kex_get_method_by_name(s, method_len, mlist)) { + /* Strip out unsupported method */ + if (p) { + memcpy(s, p + 1, strlen(s) - method_len); + } else { + if (s > newprefs) { + *(--s) = '\0'; + } else { + *s = '\0'; + } + } + } + + s = p ? (p + 1) : NULL; + } + + if (strlen(newprefs) == 0) { + LIBSSH2_FREE(session, newprefs); + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "The requested method(s) are not currently " + "supported"); + } + + if (*prefvar) { + LIBSSH2_FREE(session, *prefvar); + } + *prefvar = newprefs; + + return 0; +} + +/* + * libssh2_session_supported_algs() + * returns a number of returned algorithms (a positive number) on success, + * a negative number on failure + */ + +LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session, + int method_type, + const char*** algs) +{ + unsigned int i; + unsigned int j; + unsigned int ialg; + const LIBSSH2_COMMON_METHOD **mlist; + + /* to prevent coredumps due to dereferencing of NULL */ + if (NULL == algs) + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "algs must not be NULL"); + + switch (method_type) { + case LIBSSH2_METHOD_KEX: + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods; + break; + + case LIBSSH2_METHOD_HOSTKEY: + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods(); + break; + + case LIBSSH2_METHOD_CRYPT_CS: + case LIBSSH2_METHOD_CRYPT_SC: + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods(); + break; + + case LIBSSH2_METHOD_MAC_CS: + case LIBSSH2_METHOD_MAC_SC: + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods(); + break; + + case LIBSSH2_METHOD_COMP_CS: + case LIBSSH2_METHOD_COMP_SC: + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_comp_methods(session); + break; + + default: + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unknown method type"); + } /* switch */ + + /* weird situation */ + if (NULL==mlist) + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "No algorithm found"); + + /* + mlist is looped through twice. The first time to find the number od + supported algorithms (needed to allocate the proper size of array) and + the second time to actually copy the pointers. Typically this function + will not be called often (typically at the beginning of a session) and + the number of algorithms (i.e. niumber of iterations in one loop) will + not be high (typically it will not exceed 20) for quite a long time. + + So double looping really shouldn't be an issue and it is definitely a + better solution than reallocation several times. + */ + + /* count the number of supported algorithms */ + for ( i=0, ialg=0; NULL!=mlist[i]; i++) { + /* do not count fields with NULL name */ + if (mlist[i]->name) + ialg++; + } + + /* weird situation, no algorithm found */ + if (0==ialg) + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "No algorithm found"); + + /* allocate buffer */ + *algs = (const char**) LIBSSH2_ALLOC(session, ialg*sizeof(const char*)); + if ( NULL==*algs ) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Memory allocation failed"); + } + /* Past this point *algs must be deallocated in case of an error!! */ + + /* copy non-NULL pointers only */ + for ( i=0, j=0; NULL!=mlist[i] && jname ){ + /* maybe a weird situation but if it occurs, do not include NULL + pointers */ + continue; + } + + /* note that [] has higher priority than * (dereferencing) */ + (*algs)[j++] = mlist[i]->name; + } + + /* correct number of pointers copied? (test the code above) */ + if ( j!=ialg ) { + /* deallocate buffer */ + LIBSSH2_FREE(session, (void *)*algs); + *algs = NULL; + + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "Internal error"); + } + + return ialg; +} diff --git a/libssh2/src/knownhost.c b/libssh2/src/knownhost.c new file mode 100644 index 000000000..a32dcf876 --- /dev/null +++ b/libssh2/src/knownhost.c @@ -0,0 +1,1245 @@ +/* + * Copyright (c) 2009-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" + +struct known_host { + struct list_node node; + char *name; /* points to the name or the hash (allocated) */ + size_t name_len; /* needed for hashed data */ + int port; /* if non-zero, a specific port this key is for on this + host */ + int typemask; /* plain, sha1, custom, ... */ + char *salt; /* points to binary salt (allocated) */ + size_t salt_len; /* size of salt */ + char *key; /* the (allocated) associated key. This is kept base64 + encoded in memory. */ + char *key_type_name; /* the (allocated) key type name */ + size_t key_type_len; /* size of key_type_name */ + char *comment; /* the (allocated) optional comment text, may be + NULL */ + size_t comment_len; /* the size of comment */ + + /* this is the struct we expose externally */ + struct libssh2_knownhost external; +}; + +struct _LIBSSH2_KNOWNHOSTS +{ + LIBSSH2_SESSION *session; /* the session this "belongs to" */ + struct list_head head; +}; + +static void free_host(LIBSSH2_SESSION *session, struct known_host *entry) +{ + if(entry) { + if(entry->comment) + LIBSSH2_FREE(session, entry->comment); + if (entry->key_type_name) + LIBSSH2_FREE(session, entry->key_type_name); + if(entry->key) + LIBSSH2_FREE(session, entry->key); + if(entry->salt) + LIBSSH2_FREE(session, entry->salt); + if(entry->name) + LIBSSH2_FREE(session, entry->name); + LIBSSH2_FREE(session, entry); + } +} + +/* + * libssh2_knownhost_init + * + * Init a collection of known hosts. Returns the pointer to a collection. + * + */ +LIBSSH2_API LIBSSH2_KNOWNHOSTS * +libssh2_knownhost_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_KNOWNHOSTS *knh = + LIBSSH2_ALLOC(session, sizeof(struct _LIBSSH2_KNOWNHOSTS)); + + if(!knh) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for known-hosts " + "collection"); + return NULL; + } + + knh->session = session; + + _libssh2_list_init(&knh->head); + + return knh; +} + +#define KNOWNHOST_MAGIC 0xdeadcafe +/* + * knownhost_to_external() + * + * Copies data from the internal to the external representation struct. + * + */ +static struct libssh2_knownhost *knownhost_to_external(struct known_host *node) +{ + struct libssh2_knownhost *ext = &node->external; + + ext->magic = KNOWNHOST_MAGIC; + ext->node = node; + ext->name = ((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) == + LIBSSH2_KNOWNHOST_TYPE_PLAIN)? node->name:NULL; + ext->key = node->key; + ext->typemask = node->typemask; + + return ext; +} + +static int +knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *salt, + const char *key_type_name, size_t key_type_len, + const char *key, size_t keylen, + const char *comment, size_t commentlen, + int typemask, struct libssh2_knownhost **store) +{ + struct known_host *entry; + size_t hostlen = strlen(host); + int rc; + char *ptr; + unsigned int ptrlen; + + /* make sure we have a key type set */ + if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK)) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, + "No key type set"); + + if(!(entry = LIBSSH2_CALLOC(hosts->session, sizeof(struct known_host)))) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for known host " + "entry"); + + entry->typemask = typemask; + + switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { + case LIBSSH2_KNOWNHOST_TYPE_PLAIN: + case LIBSSH2_KNOWNHOST_TYPE_CUSTOM: + entry->name = LIBSSH2_ALLOC(hosts->session, hostlen+1); + if(!entry->name) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for host name"); + goto error; + } + memcpy(entry->name, host, hostlen+1); + entry->name_len = hostlen; + break; + case LIBSSH2_KNOWNHOST_TYPE_SHA1: + rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen, + host, hostlen); + if(rc) + goto error; + entry->name = ptr; + entry->name_len = ptrlen; + + rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen, + salt, strlen(salt)); + if(rc) + goto error; + entry->salt = ptr; + entry->salt_len = ptrlen; + break; + default: + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unknown host name type"); + goto error; + } + + if(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64) { + /* the provided key is base64 encoded already */ + if(!keylen) + keylen = strlen(key); + entry->key = LIBSSH2_ALLOC(hosts->session, keylen+1); + if(!entry->key) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for key"); + goto error; + } + memcpy(entry->key, key, keylen+1); + entry->key[keylen]=0; /* force a terminating zero trailer */ + } + else { + /* key is raw, we base64 encode it and store it as such */ + size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen, + &ptr); + if(!nlen) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "base64-encoded key"); + goto error; + } + + entry->key = ptr; + } + + if (key_type_name && ((typemask & LIBSSH2_KNOWNHOST_KEY_MASK) == + LIBSSH2_KNOWNHOST_KEY_UNKNOWN)) { + entry->key_type_name = LIBSSH2_ALLOC(hosts->session, key_type_len+1); + if (!entry->key_type_name) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for key type"); + goto error; + } + memcpy(entry->key_type_name, key_type_name, key_type_len); + entry->key_type_name[key_type_len]=0; + entry->key_type_len = key_type_len; + } + + if (comment) { + entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen+1); + if(!entry->comment) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for comment"); + goto error; + } + memcpy(entry->comment, comment, commentlen+1); + entry->comment[commentlen]=0; /* force a terminating zero trailer */ + entry->comment_len = commentlen; + } + else { + entry->comment = NULL; + } + + /* add this new host to the big list of known hosts */ + _libssh2_list_add(&hosts->head, &entry->node); + + if(store) + *store = knownhost_to_external(entry); + + return LIBSSH2_ERROR_NONE; + error: + free_host(hosts->session, entry); + return rc; +} + +/* + * libssh2_knownhost_add + * + * Add a host and its associated key to the collection of known hosts. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +LIBSSH2_API int +libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *salt, + const char *key, size_t keylen, + int typemask, struct libssh2_knownhost **store) +{ + return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, NULL, + 0, typemask, store); +} + + +/* + * libssh2_knownhost_addc + * + * Add a host and its associated key to the collection of known hosts. + * + * Takes a comment argument that may be NULL. A NULL comment indicates + * there is no comment and the entry will end directly after the key + * when written out to a file. An empty string "" comment will indicate an + * empty comment which will cause a single space to be written after the key. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +LIBSSH2_API int +libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *salt, + const char *key, size_t keylen, + const char *comment, size_t commentlen, + int typemask, struct libssh2_knownhost **store) +{ + return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, + comment, commentlen, typemask, store); +} + +/* + * knownhost_check + * + * Check a host and its associated key against the collection of known hosts. + * + * The typemask is the type/format of the given host name and key + * + * plain - ascii "hostname.domain.tld" + * sha1 - NOT SUPPORTED AS INPUT + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_FAILURE + * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND + * LIBSSH2_KNOWNHOST_CHECK_MATCH + * LIBSSH2_KNOWNHOST_CHECK_MISMATCH + */ +static int +knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, + const char *hostp, int port, + const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **ext) +{ + struct known_host *node; + struct known_host *badkey = NULL; + int type = typemask & LIBSSH2_KNOWNHOST_TYPE_MASK; + char *keyalloc = NULL; + int rc = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND; + char hostbuff[270]; /* most host names can't be longer than like 256 */ + const char *host; + int numcheck; /* number of host combos to check */ + int match = 0; + + if(type == LIBSSH2_KNOWNHOST_TYPE_SHA1) + /* we can't work with a sha1 as given input */ + return LIBSSH2_KNOWNHOST_CHECK_MISMATCH; + + /* if a port number is given, check for a '[host]:port' first before the + plain 'host' */ + if(port >= 0) { + int len = snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port); + if (len < 0 || len >= (int)sizeof(hostbuff)) { + _libssh2_error(hosts->session, + LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Known-host write buffer too small"); + return LIBSSH2_KNOWNHOST_CHECK_FAILURE; + } + host = hostbuff; + numcheck = 2; /* check both combos, start with this */ + } + else { + host = hostp; + numcheck = 1; /* only check this host version */ + } + + if(!(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64)) { + /* we got a raw key input, convert it to base64 for the checks below */ + size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen, + &keyalloc); + if(!nlen) { + _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for base64-encoded " + "key"); + return LIBSSH2_KNOWNHOST_CHECK_FAILURE; + } + + /* make the key point to this */ + key = keyalloc; + } + + do { + node = _libssh2_list_first(&hosts->head); + while (node) { + switch(node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { + case LIBSSH2_KNOWNHOST_TYPE_PLAIN: + if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) + match = !strcmp(host, node->name); + break; + case LIBSSH2_KNOWNHOST_TYPE_CUSTOM: + if(type == LIBSSH2_KNOWNHOST_TYPE_CUSTOM) + match = !strcmp(host, node->name); + break; + case LIBSSH2_KNOWNHOST_TYPE_SHA1: + if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) { + /* when we have the sha1 version stored, we can use a + plain input to produce a hash to compare with the + stored hash. + */ + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_hmac_ctx ctx; + libssh2_hmac_ctx_init(ctx); + + if(SHA_DIGEST_LENGTH != node->name_len) { + /* the name hash length must be the sha1 size or + we can't match it */ + break; + } + libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt, + node->salt_len); + libssh2_hmac_update(ctx, (unsigned char *)host, + strlen(host)); + libssh2_hmac_final(ctx, hash); + libssh2_hmac_cleanup(&ctx); + + if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH)) + /* this is a node we're interested in */ + match = 1; + } + break; + default: /* unsupported type */ + break; + } + if(match) { + int host_key_type = typemask & LIBSSH2_KNOWNHOST_KEY_MASK; + int known_key_type = + node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK; + /* match on key type as follows: + - never match on an unknown key type + - if key_type is set to zero, ignore it an match always + - otherwise match when both key types are equal + */ + if ( (host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN ) && + ( (host_key_type == 0) || + (host_key_type == known_key_type) ) ) { + /* host name and key type match, now compare the keys */ + if(!strcmp(key, node->key)) { + /* they match! */ + if (ext) + *ext = knownhost_to_external(node); + badkey = NULL; + rc = LIBSSH2_KNOWNHOST_CHECK_MATCH; + break; + } + else { + /* remember the first node that had a host match but a + failed key match since we continue our search from + here */ + if(!badkey) + badkey = node; + } + } + match = 0; /* don't count this as a match anymore */ + } + node= _libssh2_list_next(&node->node); + } + host = hostp; + } while(!match && --numcheck); + + if(badkey) { + /* key mismatch */ + if (ext) + *ext = knownhost_to_external(badkey); + rc = LIBSSH2_KNOWNHOST_CHECK_MISMATCH; + } + + if(keyalloc) + LIBSSH2_FREE(hosts->session, keyalloc); + + return rc; +} + +/* + * libssh2_knownhost_check + * + * Check a host and its associated key against the collection of known hosts. + * + * The typemask is the type/format of the given host name and key + * + * plain - ascii "hostname.domain.tld" + * sha1 - NOT SUPPORTED AS INPUT + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_FAILURE + * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND + * LIBSSH2_KNOWNHOST_CHECK_MATCH + * LIBSSH2_KNOWNHOST_CHECK_MISMATCH + */ +LIBSSH2_API int +libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, + const char *hostp, const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **ext) +{ + return knownhost_check(hosts, hostp, -1, key, keylen, + typemask, ext); +} + +/* + * libssh2_knownhost_checkp + * + * Check a host+port and its associated key against the collection of known + * hosts. + * + * Note that if 'port' is specified as greater than zero, the check function + * will be able to check for a dedicated key for this particular host+port + * combo, and if 'port' is negative it only checks for the generic host key. + * + * The typemask is the type/format of the given host name and key + * + * plain - ascii "hostname.domain.tld" + * sha1 - NOT SUPPORTED AS INPUT + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_FAILURE + * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND + * LIBSSH2_KNOWNHOST_CHECK_MATCH + * LIBSSH2_KNOWNHOST_CHECK_MISMATCH + */ +LIBSSH2_API int +libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts, + const char *hostp, int port, + const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **ext) +{ + return knownhost_check(hosts, hostp, port, key, keylen, + typemask, ext); +} + + +/* + * libssh2_knownhost_del + * + * Remove a host from the collection of known hosts. + * + */ +LIBSSH2_API int +libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *entry) +{ + struct known_host *node; + + /* check that this was retrieved the right way or get out */ + if(!entry || (entry->magic != KNOWNHOST_MAGIC)) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, + "Invalid host information"); + + /* get the internal node pointer */ + node = entry->node; + + /* unlink from the list of all hosts */ + _libssh2_list_remove(&node->node); + + /* clear the struct now since the memory in which it is allocated is + about to be freed! */ + memset(entry, 0, sizeof(struct libssh2_knownhost)); + + /* free all resources */ + free_host(hosts->session, node); + + return 0; +} + +/* + * libssh2_knownhost_free + * + * Free an entire collection of known hosts. + * + */ +LIBSSH2_API void +libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts) +{ + struct known_host *node; + struct known_host *next; + + for(node = _libssh2_list_first(&hosts->head); node; node = next) { + next = _libssh2_list_next(&node->node); + free_host(hosts->session, node); + } + LIBSSH2_FREE(hosts->session, hosts); +} + + +/* old style plain text: [name]([,][name])* + + for the sake of simplicity, we add them as separate hosts with the same + key +*/ +static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, size_t hostlen, + const char *key_type_name, size_t key_type_len, + const char *key, size_t keylen, int key_type, + const char *comment, size_t commentlen) +{ + int rc = 0; + size_t namelen = 0; + const char *name = host + hostlen; + + if(hostlen < 1) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(no host names)"); + + while(name > host) { + --name; + ++namelen; + + /* when we get the the start or see a comma coming up, add the host + name to the collection */ + if((name == host) || (*(name-1) == ',')) { + + char hostbuf[256]; + + /* make sure we don't overflow the buffer */ + if(namelen >= sizeof(hostbuf)-1) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(unexpected length)"); + + /* copy host name to the temp buffer and zero terminate */ + memcpy(hostbuf, name, namelen); + hostbuf[namelen]=0; + + rc = knownhost_add(hosts, hostbuf, NULL, + key_type_name, key_type_len, + key, keylen, + comment, commentlen, + key_type | LIBSSH2_KNOWNHOST_TYPE_PLAIN | + LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); + if(rc) + return rc; + + if(name > host) { + namelen = 0; + --name; /* skip comma */ + } + } + } + + return rc; +} + +/* |1|[salt]|[hash] */ +static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, size_t hostlen, + const char *key_type_name, size_t key_type_len, + const char *key, size_t keylen, int key_type, + const char *comment, size_t commentlen) +{ + const char *p; + char saltbuf[32]; + char hostbuf[256]; + + const char *salt = &host[3]; /* skip the magic marker */ + hostlen -= 3; /* deduct the marker */ + + /* this is where the salt starts, find the end of it */ + for(p = salt; *p && (*p != '|'); p++) + ; + + if(*p=='|') { + const char *hash = NULL; + size_t saltlen = p - salt; + if(saltlen >= (sizeof(saltbuf)-1)) /* weird length */ + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(unexpectedly long salt)"); + + memcpy(saltbuf, salt, saltlen); + saltbuf[saltlen] = 0; /* zero terminate */ + salt = saltbuf; /* point to the stack based buffer */ + + hash = p+1; /* the host hash is after the separator */ + + /* now make the host point to the hash */ + host = hash; + hostlen -= saltlen+1; /* deduct the salt and separator */ + + /* check that the lengths seem sensible */ + if(hostlen >= sizeof(hostbuf)-1) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(unexpected length)"); + + memcpy(hostbuf, host, hostlen); + hostbuf[hostlen]=0; + + return knownhost_add(hosts, hostbuf, salt, + key_type_name, key_type_len, + key, keylen, + comment, commentlen, + key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 | + LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); + } + else + return 0; /* XXX: This should be an error, shouldn't it? */ +} + +/* + * hostline() + * + * Parse a single known_host line pre-split into host and key. + * + * The key part may include an optional comment which will be parsed here + * for ssh-rsa and ssh-dsa keys. Comments in other key types aren't handled. + * + * The function assumes new-lines have already been removed from the arguments. + */ +static int hostline(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, size_t hostlen, + const char *key, size_t keylen) +{ + const char *comment = NULL; + const char *key_type_name = NULL; + size_t commentlen = 0; + size_t key_type_len = 0; + int key_type; + + /* make some checks that the lengths seem sensible */ + if(keylen < 20) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(key too short)"); + + switch(key[0]) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + key_type = LIBSSH2_KNOWNHOST_KEY_RSA1; + + /* Note that the old-style keys (RSA1) aren't truly base64, but we + * claim it is for now since we can get away with strcmp()ing the + * entire anything anyway! We need to check and fix these to make them + * work properly. + */ + break; + + default: + key_type_name = key; + while (keylen && *key && + (*key != ' ') && (*key != '\t')) { + key++; + keylen--; + } + key_type_len = key - key_type_name; + + if (!strncmp(key_type_name, "ssh-dss", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS; + else if (!strncmp(key_type_name, "ssh-rsa", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA; + else + key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN; + + /* skip whitespaces */ + while((*key ==' ') || (*key == '\t')) { + key++; + keylen--; + } + + comment = key; + commentlen = keylen; + + /* move over key */ + while(commentlen && *comment && + (*comment != ' ') && (*comment != '\t')) { + comment++; + commentlen--; + } + + /* reduce key by comment length */ + keylen -= commentlen; + + /* Distinguish empty comment (a space) from no comment (no space) */ + if (commentlen == 0) + comment = NULL; + + /* skip whitespaces */ + while(commentlen && *comment && + ((*comment ==' ') || (*comment == '\t'))) { + comment++; + commentlen--; + } + break; + } + + /* Figure out host format */ + if((hostlen >2) && memcmp(host, "|1|", 3)) { + /* old style plain text: [name]([,][name])* + + for the sake of simplicity, we add them as separate hosts with the + same key + */ + return oldstyle_hostline(hosts, host, hostlen, key_type_name, + key_type_len, key, keylen, key_type, + comment, commentlen); + } + else { + /* |1|[salt]|[hash] */ + return hashed_hostline(hosts, host, hostlen, key_type_name, + key_type_len, key, keylen, key_type, + comment, commentlen); + } +} + +/* + * libssh2_knownhost_readline() + * + * Pass in a line of a file of 'type'. + * + * LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type. + * + * OpenSSH line format: + * + * + * + * Where the two parts can be created like: + * + * can be either + * or + * + * consists of + * [name] optionally followed by [,name] one or more times + * + * consists of + * |1||hash + * + * can be one of: + * [RSA bits] [e] [n as a decimal number] + * 'ssh-dss' [base64-encoded-key] + * 'ssh-rsa' [base64-encoded-key] + * + */ +LIBSSH2_API int +libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts, + const char *line, size_t len, int type) +{ + const char *cp; + const char *hostp; + const char *keyp; + size_t hostlen; + size_t keylen; + int rc; + + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + cp = line; + + /* skip leading whitespaces */ + while(len && ((*cp==' ') || (*cp == '\t'))) { + cp++; + len--; + } + + if(!len || !*cp || (*cp == '#') || (*cp == '\n')) + /* comment or empty line */ + return LIBSSH2_ERROR_NONE; + + /* the host part starts here */ + hostp = cp; + + /* move over the host to the separator */ + while(len && *cp && (*cp!=' ') && (*cp != '\t')) { + cp++; + len--; + } + + hostlen = cp - hostp; + + /* the key starts after the whitespaces */ + while(len && *cp && ((*cp==' ') || (*cp == '\t'))) { + cp++; + len--; + } + + if(!*cp || !len) /* illegal line */ + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line"); + + keyp = cp; /* the key starts here */ + keylen = len; + + /* check if the line (key) ends with a newline and if so kill it */ + while(len && *cp && (*cp != '\n')) { + cp++; + len--; + } + + /* zero terminate where the newline is */ + if(*cp == '\n') + keylen--; /* don't include this in the count */ + + /* deal with this one host+key line */ + rc = hostline(hosts, hostp, hostlen, keyp, keylen); + if(rc) + return rc; /* failed */ + + return LIBSSH2_ERROR_NONE; /* success */ +} + +/* + * libssh2_knownhost_readfile + * + * Read hosts+key pairs from a given file. + * + * Returns a negative value for error or number of successfully added hosts. + * + */ + +LIBSSH2_API int +libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type) +{ + FILE *file; + int num = 0; + char buf[2048]; + + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + file = fopen(filename, "r"); + if(file) { + while(fgets(buf, sizeof(buf), file)) { + if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type)) { + num = _libssh2_error(hosts->session, LIBSSH2_ERROR_KNOWN_HOSTS, + "Failed to parse known hosts file"); + break; + } + num++; + } + fclose(file); + } + else + return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, + "Failed to open file"); + + return num; +} + +/* + * knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given + * output buffer is too small to hold the desired output. The 'outlen' field + * will then contain the size libssh2 wanted to store, which then is the + * smallest sufficient buffer it would require. + * + */ +static int +knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, + struct known_host *node, + char *buf, size_t buflen, + size_t *outlen, int type) +{ + size_t required_size; + + const char *key_type_name; + size_t key_type_len; + + /* we only support this single file type for now, bail out on all other + attempts */ + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + switch(node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) { + case LIBSSH2_KNOWNHOST_KEY_RSA1: + key_type_name = NULL; + key_type_len = 0; + break; + case LIBSSH2_KNOWNHOST_KEY_SSHRSA: + key_type_name = "ssh-rsa"; + key_type_len = 7; + break; + case LIBSSH2_KNOWNHOST_KEY_SSHDSS: + key_type_name = "ssh-dss"; + key_type_len = 7; + break; + case LIBSSH2_KNOWNHOST_KEY_UNKNOWN: + key_type_name = node->key_type_name; + if (key_type_name) { + key_type_len = node->key_type_len; + break; + } + /* otherwise fallback to default and error */ + default: + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host entry"); + } + + /* When putting together the host line there are three aspects to consider: + - Hashed (SHA1) or unhashed hostname + - key name or no key name (RSA1) + - comment or no comment + + This means there are 2^3 different formats: + ("|1|%s|%s %s %s %s\n", salt, hashed_host, key_name, key, comment) + ("|1|%s|%s %s %s\n", salt, hashed_host, key_name, key) + ("|1|%s|%s %s %s\n", salt, hashed_host, key, comment) + ("|1|%s|%s %s\n", salt, hashed_host, key) + ("%s %s %s %s\n", host, key_name, key, comment) + ("%s %s %s\n", host, key_name, key) + ("%s %s %s\n", host, key, comment) + ("%s %s\n", host, key) + + Even if the buffer is too small, we have to set outlen to the number of + characters the complete line would have taken. We also don't write + anything to the buffer unless we are sure we can write everything to the + buffer. */ + + required_size = strlen(node->key); + + if(key_type_len) + required_size += key_type_len + 1; /* ' ' = 1 */ + if(node->comment) + required_size += node->comment_len + 1; /* ' ' = 1 */ + + if((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) == + LIBSSH2_KNOWNHOST_TYPE_SHA1) { + char *namealloc; + size_t name_base64_len; + char *saltalloc; + size_t salt_base64_len; + + name_base64_len = _libssh2_base64_encode(hosts->session, node->name, + node->name_len, &namealloc); + if(!name_base64_len) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "base64-encoded host name"); + + salt_base64_len = _libssh2_base64_encode(hosts->session, + node->salt, node->salt_len, + &saltalloc); + if(!salt_base64_len) { + LIBSSH2_FREE(hosts->session, namealloc); + return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "base64-encoded salt"); + } + + required_size += salt_base64_len + name_base64_len + 7; + /* |1| + | + ' ' + \n + \0 = 7 */ + + if(required_size <= buflen) { + if(node->comment && key_type_len) + snprintf(buf, buflen, "|1|%s|%s %s %s %s\n", saltalloc, + namealloc, key_type_name, node->key, node->comment); + else if (node->comment) + snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, + node->key, node->comment); + else if (key_type_len) + snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, + key_type_name, node->key); + else + snprintf(buf, buflen, "|1|%s|%s %s\n", saltalloc, namealloc, + node->key); + } + + LIBSSH2_FREE(hosts->session, namealloc); + LIBSSH2_FREE(hosts->session, saltalloc); + } + else { + required_size += node->name_len + 3; + /* ' ' + '\n' + \0 = 3 */ + + if(required_size <= buflen) { + if(node->comment && key_type_len) + snprintf(buf, buflen, "%s %s %s %s\n", node->name, + key_type_name, node->key, node->comment); + else if (node->comment) + snprintf(buf, buflen, "%s %s %s\n", node->name, node->key, + node->comment); + else if (key_type_len) + snprintf(buf, buflen, "%s %s %s\n", node->name, key_type_name, + node->key); + else + snprintf(buf, buflen, "%s %s\n", node->name, node->key); + } + } + + /* we report the full length of the data with the trailing zero excluded */ + *outlen = required_size-1; + + if(required_size <= buflen) + return LIBSSH2_ERROR_NONE; + else + return _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Known-host write buffer too small"); +} + +/* + * libssh2_knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given + * output buffer is too small to hold the desired output. + */ +LIBSSH2_API int +libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *known, + char *buffer, size_t buflen, + size_t *outlen, /* the amount of written data */ + int type) +{ + struct known_host *node; + + if(known->magic != KNOWNHOST_MAGIC) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, + "Invalid host information"); + + node = known->node; + + return knownhost_writeline(hosts, node, buffer, buflen, outlen, type); +} + +/* + * libssh2_knownhost_writefile() + * + * Write hosts+key pairs to the given file. + */ +LIBSSH2_API int +libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type) +{ + struct known_host *node; + FILE *file; + int rc = LIBSSH2_ERROR_NONE; + char buffer[2048]; + + /* we only support this single file type for now, bail out on all other + attempts */ + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + file = fopen(filename, "w"); + if(!file) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, + "Failed to open file"); + + for(node = _libssh2_list_first(&hosts->head); + node; + node = _libssh2_list_next(&node->node)) { + size_t wrote = 0; + size_t nwrote; + rc = knownhost_writeline(hosts, node, buffer, sizeof(buffer), &wrote, + type); + if(rc) + break; + + nwrote = fwrite(buffer, 1, wrote, file); + if(nwrote != wrote) { + /* failed to write the whole thing, bail out */ + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, + "Write failed"); + break; + } + } + fclose(file); + + return rc; +} + + +/* + * libssh2_knownhost_get() + * + * Traverse the internal list of known hosts. Pass NULL to 'prev' to get + * the first one. + * + * Returns: + * 0 if a fine host was stored in 'store' + * 1 if end of hosts + * [negative] on errors + */ +LIBSSH2_API int +libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost **ext, + struct libssh2_knownhost *oprev) +{ + struct known_host *node; + if(oprev && oprev->node) { + /* we have a starting point */ + struct known_host *prev = oprev->node; + + /* get the next node in the list */ + node = _libssh2_list_next(&prev->node); + + } + else + node = _libssh2_list_first(&hosts->head); + + if(!node) + /* no (more) node */ + return 1; + + *ext = knownhost_to_external(node); + + return 0; +} diff --git a/libssh2/src/libgcrypt.c b/libssh2/src/libgcrypt.c new file mode 100644 index 000000000..366d007a3 --- /dev/null +++ b/libssh2/src/libgcrypt.c @@ -0,0 +1,627 @@ +/* Copyright (C) 2008, 2009, Simon Josefsson + * Copyright (C) 2006, 2007, The Written Word, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */ + +#include + +int +_libssh2_rsa_new(libssh2_rsa_ctx ** rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen) +{ + int rc; + (void) e1data; + (void) e1len; + (void) e2data; + (void) e2len; + + if (ddata) { + rc = gcry_sexp_build + (rsa, NULL, + "(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))", + nlen, ndata, elen, edata, dlen, ddata, plen, pdata, + qlen, qdata, coefflen, coeffdata); + } else { + rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))", + nlen, ndata, elen, edata); + } + if (rc) { + *rsa = NULL; + return -1; + } + + return 0; +} + +int +_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + gcry_sexp_t s_sig, s_hash; + int rc = -1; + + libssh2_sha1(m, m_len, hash); + + rc = gcry_sexp_build(&s_hash, NULL, + "(data (flags pkcs1) (hash sha1 %b))", + SHA_DIGEST_LENGTH, hash); + if (rc != 0) { + return -1; + } + + rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig); + if (rc != 0) { + gcry_sexp_release(s_hash); + return -1; + } + + rc = gcry_pk_verify(s_sig, s_hash, rsa); + gcry_sexp_release(s_sig); + gcry_sexp_release(s_hash); + + return (rc == 0) ? 0 : -1; +} + +int +_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx, + const unsigned char *p, + unsigned long p_len, + const unsigned char *q, + unsigned long q_len, + const unsigned char *g, + unsigned long g_len, + const unsigned char *y, + unsigned long y_len, + const unsigned char *x, unsigned long x_len) +{ + int rc; + + if (x_len) { + rc = gcry_sexp_build + (dsactx, NULL, + "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", + p_len, p, q_len, q, g_len, g, y_len, y, x_len, x); + } else { + rc = gcry_sexp_build(dsactx, NULL, + "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", + p_len, p, q_len, q, g_len, g, y_len, y); + } + + if (rc) { + *dsactx = NULL; + return -1; + } + + return 0; +} + +int +_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unimplemented in libgcrypt backend"); +} + +int +_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + FILE *fp; + unsigned char *data, *save_data; + unsigned int datalen; + int ret; + unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff; + unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen; + + (void) passphrase; + + fp = fopen(filename, "r"); + if (!fp) { + return -1; + } + + ret = _libssh2_pem_parse(session, + "-----BEGIN RSA PRIVATE KEY-----", + "-----END RSA PRIVATE KEY-----", + fp, &data, &datalen); + fclose(fp); + if (ret) { + return -1; + } + + save_data = data; + + if (_libssh2_pem_decode_sequence(&data, &datalen)) { + ret = -1; + goto fail; + } +/* First read Version field (should be 0). */ + ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); + if (ret != 0 || (nlen != 1 && *n != '\0')) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen); + if (ret != 0) { + ret = -1; + goto fail; + } + + if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen, + q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) { + ret = -1; + goto fail; + } + + ret = 0; + + fail: + LIBSSH2_FREE(session, save_data); + return ret; +} + +int +_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unimplemented in libgcrypt backend"); +} + +int +_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + FILE *fp; + unsigned char *data, *save_data; + unsigned int datalen; + int ret; + unsigned char *p, *q, *g, *y, *x; + unsigned int plen, qlen, glen, ylen, xlen; + + (void) passphrase; + + fp = fopen(filename, "r"); + if (!fp) { + return -1; + } + + ret = _libssh2_pem_parse(session, + "-----BEGIN DSA PRIVATE KEY-----", + "-----END DSA PRIVATE KEY-----", + fp, &data, &datalen); + fclose(fp); + if (ret) { + return -1; + } + + save_data = data; + + if (_libssh2_pem_decode_sequence(&data, &datalen)) { + ret = -1; + goto fail; + } + +/* First read Version field (should be 0). */ + ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); + if (ret != 0 || (plen != 1 && *p != '\0')) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + if (datalen != 0) { + ret = -1; + goto fail; + } + + if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) { + ret = -1; + goto fail; + } + + ret = 0; + + fail: + LIBSSH2_FREE(session, save_data); + return ret; +} + +int +_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, size_t *signature_len) +{ + gcry_sexp_t sig_sexp; + gcry_sexp_t data; + int rc; + const char *tmp; + size_t size; + + if (hash_len != SHA_DIGEST_LENGTH) { + return -1; + } + + if (gcry_sexp_build(&data, NULL, + "(data (flags pkcs1) (hash sha1 %b))", + hash_len, hash)) { + return -1; + } + + rc = gcry_pk_sign(&sig_sexp, data, rsactx); + + gcry_sexp_release(data); + + if (rc != 0) { + return -1; + } + + data = gcry_sexp_find_token(sig_sexp, "s", 0); + if (!data) { + return -1; + } + + tmp = gcry_sexp_nth_data(data, 1, &size); + if (!tmp) { + return -1; + } + + if (tmp[0] == '\0') { + tmp++; + size--; + } + + *signature = LIBSSH2_ALLOC(session, size); + if (!*signature) { + return -1; + } + memcpy(*signature, tmp, size); + *signature_len = size; + + return rc; +} + +int +_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *sig) +{ + unsigned char zhash[SHA_DIGEST_LENGTH + 1]; + gcry_sexp_t sig_sexp; + gcry_sexp_t data; + int ret; + const char *tmp; + size_t size; + + if (hash_len != SHA_DIGEST_LENGTH) { + return -1; + } + + memcpy(zhash + 1, hash, hash_len); + zhash[0] = 0; + + if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) { + return -1; + } + + ret = gcry_pk_sign(&sig_sexp, data, dsactx); + + gcry_sexp_release(data); + + if (ret != 0) { + return -1; + } + + memset(sig, 0, 40); + +/* Extract R. */ + + data = gcry_sexp_find_token(sig_sexp, "r", 0); + if (!data) + goto err; + + tmp = gcry_sexp_nth_data(data, 1, &size); + if (!tmp) + goto err; + + if (tmp[0] == '\0') { + tmp++; + size--; + } + + if (size < 1 || size > 20) + goto err; + + memcpy(sig + (20 - size), tmp, size); + + gcry_sexp_release(data); + +/* Extract S. */ + + data = gcry_sexp_find_token(sig_sexp, "s", 0); + if (!data) + goto err; + + tmp = gcry_sexp_nth_data(data, 1, &size); + if (!tmp) + goto err; + + if (tmp[0] == '\0') { + tmp++; + size--; + } + + if (size < 1 || size > 20) + goto err; + + memcpy(sig + 20 + (20 - size), tmp, size); + goto out; + + err: + ret = -1; + + out: + if (sig_sexp) { + gcry_sexp_release(sig_sexp); + } + if (data) { + gcry_sexp_release(data); + } + return ret; +} + +int +_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH + 1]; + gcry_sexp_t s_sig, s_hash; + int rc = -1; + + libssh2_sha1(m, m_len, hash + 1); + hash[0] = 0; + + if (gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))", + SHA_DIGEST_LENGTH + 1, hash)) { + return -1; + } + + if (gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))", + 20, sig, 20, sig + 20)) { + gcry_sexp_release(s_hash); + return -1; + } + + rc = gcry_pk_verify(s_sig, s_hash, dsactx); + gcry_sexp_release(s_sig); + gcry_sexp_release(s_hash); + + return (rc == 0) ? 0 : -1; +} + +int +_libssh2_cipher_init(_libssh2_cipher_ctx * h, + _libssh2_cipher_type(algo), + unsigned char *iv, unsigned char *secret, int encrypt) +{ + int ret; + int cipher = _libssh2_gcry_cipher (algo); + int mode = _libssh2_gcry_mode (algo); + int keylen = gcry_cipher_get_algo_keylen(cipher); + + (void) encrypt; + + ret = gcry_cipher_open(h, cipher, mode, 0); + if (ret) { + return -1; + } + + ret = gcry_cipher_setkey(*h, secret, keylen); + if (ret) { + gcry_cipher_close(*h); + return -1; + } + + if (mode != GCRY_CIPHER_MODE_STREAM) { + int blklen = gcry_cipher_get_algo_blklen(cipher); + if (mode == GCRY_CIPHER_MODE_CTR) + ret = gcry_cipher_setctr(*h, iv, blklen); + else + ret = gcry_cipher_setiv(*h, iv, blklen); + if (ret) { + gcry_cipher_close(*h); + return -1; + } + } + + return 0; +} + +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blklen) +{ + int cipher = _libssh2_gcry_cipher (algo); + int ret; + + if (encrypt) { + ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen); + } else { + ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen); + } + return ret; +} + +int +_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract public key from private key in memory: " + "Method unimplemented in libgcrypt backend"); +} + +int +_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to extract public key from private key file: " + "Method unimplemented in libgcrypt backend"); +} + +void _libssh2_init_aes_ctr(void) +{ + /* no implementation */ +} +#endif /* LIBSSH2_LIBGCRYPT */ diff --git a/libssh2/src/libgcrypt.h b/libssh2/src/libgcrypt.h new file mode 100644 index 000000000..11d6ad2dc --- /dev/null +++ b/libssh2/src/libgcrypt.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2008, 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007, The Written Word, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include + +#define LIBSSH2_MD5 1 + +#define LIBSSH2_HMAC_RIPEMD 1 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#define LIBSSH2_AES 1 +#define LIBSSH2_AES_CTR 1 +#define LIBSSH2_BLOWFISH 1 +#define LIBSSH2_RC4 1 +#define LIBSSH2_CAST 1 +#define LIBSSH2_3DES 1 + +#define LIBSSH2_RSA 1 +#define LIBSSH2_DSA 1 + +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 + +#define _libssh2_random(buf, len) \ + (gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1) + +#define libssh2_prepare_iovec(vec, len) /* Empty. */ + +#define libssh2_sha1_ctx gcry_md_hd_t + +/* returns 0 in case of failure */ +#define libssh2_sha1_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_SHA1, 0)) +#define libssh2_sha1_update(ctx, data, len) \ + gcry_md_write (ctx, (unsigned char *) data, len) +#define libssh2_sha1_final(ctx, out) \ + memcpy (out, gcry_md_read (ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close (ctx) +#define libssh2_sha1(message, len, out) \ + gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len) + +#define libssh2_sha256_ctx gcry_md_hd_t + +#define libssh2_sha256_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_SHA256, 0)) +#define libssh2_sha256_update(ctx, data, len) \ + gcry_md_write (ctx, (unsigned char *) data, len) +#define libssh2_sha256_final(ctx, out) \ + memcpy (out, gcry_md_read (ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close (ctx) +#define libssh2_sha256(message, len, out) \ + gcry_md_hash_buffer (GCRY_MD_SHA256, out, message, len) + +#define libssh2_md5_ctx gcry_md_hd_t + +/* returns 0 in case of failure */ +#define libssh2_md5_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_MD5, 0)) + +#define libssh2_md5_update(ctx, data, len) \ + gcry_md_write (ctx, (unsigned char *) data, len) +#define libssh2_md5_final(ctx, out) \ + memcpy (out, gcry_md_read (ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close (ctx) +#define libssh2_md5(message, len, out) \ + gcry_md_hash_buffer (GCRY_MD_MD5, out, message, len) + +#define libssh2_hmac_ctx gcry_md_hd_t +#define libssh2_hmac_ctx_init(ctx) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_update(ctx, data, datalen) \ + gcry_md_write (ctx, (unsigned char *) data, datalen) +#define libssh2_hmac_final(ctx, data) \ + memcpy (data, gcry_md_read (ctx, 0), \ + gcry_md_get_algo_dlen (gcry_md_get_algo (ctx))) +#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx); + +#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM) +#define libssh2_crypto_exit() + +#define libssh2_rsa_ctx struct gcry_sexp + +#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx) + +#define libssh2_dsa_ctx struct gcry_sexp + +#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx) + +#define _libssh2_cipher_type(name) int name +#define _libssh2_cipher_ctx gcry_cipher_hd_t + +#define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m) +#define _libssh2_gcry_cipher(c) (c >> 8) +#define _libssh2_gcry_mode(m) (m & 0xFF) + +#define _libssh2_cipher_aes256ctr \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR) +#define _libssh2_cipher_aes192ctr \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR) +#define _libssh2_cipher_aes128ctr \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR) +#define _libssh2_cipher_aes256 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_aes192 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_aes128 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_blowfish \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_arcfour \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM) +#define _libssh2_cipher_cast5 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_3des \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC) + + +#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx)) + +#define _libssh2_bn struct gcry_mpi +#define _libssh2_bn_ctx int +#define _libssh2_bn_ctx_new() 0 +#define _libssh2_bn_ctx_free(bnctx) ((void)0) +#define _libssh2_bn_init() gcry_mpi_new(0) +#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a new bignum */ +#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM) +#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m) +#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val) +#define _libssh2_bn_from_bin(bn, len, val) gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL) +#define _libssh2_bn_to_bin(bn, val) gcry_mpi_print (GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn) +#define _libssh2_bn_bytes(bn) (gcry_mpi_get_nbits (bn) / 8 + ((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1)) +#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn) +#define _libssh2_bn_free(bn) gcry_mpi_release(bn) + diff --git a/libssh2/src/libssh2.pc.in b/libssh2/src/libssh2.pc.in new file mode 100644 index 000000000..c070988b9 --- /dev/null +++ b/libssh2/src/libssh2.pc.in @@ -0,0 +1,17 @@ +########################################################################### +# libssh2 installation details +########################################################################### + +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: @PROJECT_NAME@ +URL: @PROJECT_URL@ +Description: @PROJECT_DESCRIPTION@ +Version: @LIBSSH2_VERSION@ +Requires.private: @PC_REQUIRES_PRIVATE@ +Libs: -L${libdir} -lssh2 @PC_LIBS@ +Libs.private: @PC_LIBS@ +Cflags: -I${includedir} \ No newline at end of file diff --git a/libssh2/src/libssh2_config.h.in b/libssh2/src/libssh2_config.h.in new file mode 100644 index 000000000..af4ab9ca0 --- /dev/null +++ b/libssh2/src/libssh2_config.h.in @@ -0,0 +1,261 @@ +/* src/libssh2_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the declaration of `SecureZeroMemory', and to 0 if + you don't. */ +#undef HAVE_DECL_SECUREZEROMEMORY + +/* disabled non-blocking sockets */ +#undef HAVE_DISABLED_NONBLOCKING + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the `EVP_aes_128_ctr' function. */ +#undef HAVE_EVP_AES_128_CTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* use FIONBIO for non-blocking sockets */ +#undef HAVE_FIONBIO + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* use ioctlsocket() for non-blocking sockets */ +#undef HAVE_IOCTLSOCKET + +/* use Ioctlsocket() for non-blocking sockets */ +#undef HAVE_IOCTLSOCKET_CASE + +/* Define if you have the bcrypt library. */ +#undef HAVE_LIBBCRYPT + +/* Define if you have the crypt32 library. */ +#undef HAVE_LIBCRYPT32 + +/* Define if you have the gcrypt library. */ +#undef HAVE_LIBGCRYPT + +/* Define if you have the mbedtls library. */ +#undef HAVE_LIBMBEDTLS + +/* Define if you have the ssl library. */ +#undef HAVE_LIBSSL + +/* Define if you have the z library. */ +#undef HAVE_LIBZ + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#undef HAVE_LONGLONG + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NTDEF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NTSTATUS_H + +/* use O_NONBLOCK for non-blocking sockets */ +#undef HAVE_O_NONBLOCK + +/* Define to 1 if you have the `poll' function. */ +#undef HAVE_POLL + +/* Define to 1 if you have the select function. */ +#undef HAVE_SELECT + +/* use SO_NONBLOCK for non-blocking sockets */ +#undef HAVE_SO_NONBLOCK + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtoll' function. */ +#undef HAVE_STRTOLL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINSOCK2_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WS2TCPIP_H + +/* to make a symbol visible */ +#undef LIBSSH2_API + +/* Enable clearing of memory before being freed */ +#undef LIBSSH2_CLEAR_MEMORY + +/* Enable "none" cipher -- NOT RECOMMENDED */ +#undef LIBSSH2_CRYPT_NONE + +/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ +#undef LIBSSH2_DH_GEX_NEW + +/* Compile in zlib support */ +#undef LIBSSH2_HAVE_ZLIB + +/* Use libgcrypt */ +#undef LIBSSH2_LIBGCRYPT + +/* Enable "none" MAC -- NOT RECOMMENDED */ +#undef LIBSSH2_MAC_NONE + +/* Use mbedtls */ +#undef LIBSSH2_MBEDTLS + +/* Use OpenSSL */ +#undef LIBSSH2_OPENSSL + +/* Use Windows CNG */ +#undef LIBSSH2_WINCNG + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +#undef NEED_REENTRANT + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `unsigned int' if does not define. */ +#undef size_t diff --git a/libssh2/src/libssh2_config_cmake.h.in b/libssh2/src/libssh2_config_cmake.h.in new file mode 100644 index 000000000..62723ede8 --- /dev/null +++ b/libssh2/src/libssh2_config_cmake.h.in @@ -0,0 +1,105 @@ +/* Copyright (c) 2014 Alexander Lamaison + * Copyright (c) 1999-2011 Douglas Gilbert. All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +/* Headers */ +#cmakedefine HAVE_UNISTD_H +#cmakedefine HAVE_INTTYPES_H +#cmakedefine HAVE_STDLIB_H +#cmakedefine HAVE_SYS_SELECT_H +#cmakedefine HAVE_SYS_UIO_H +#cmakedefine HAVE_SYS_SOCKET_H +#cmakedefine HAVE_SYS_IOCTL_H +#cmakedefine HAVE_SYS_TIME_H +#cmakedefine HAVE_SYS_UN_H +#cmakedefine HAVE_WINDOWS_H +#cmakedefine HAVE_WS2TCPIP_H +#cmakedefine HAVE_WINSOCK2_H +#cmakedefine HAVE_NTDEF_H +#cmakedefine HAVE_NTSTATUS_H + +/* Libraries */ +#cmakedefine HAVE_LIBCRYPT32 + +/* Types */ +#cmakedefine HAVE_LONGLONG + +/* Functions */ +#cmakedefine HAVE_GETTIMEOFDAY +#cmakedefine HAVE_INET_ADDR +#cmakedefine HAVE_POLL +#cmakedefine HAVE_SELECT +#cmakedefine HAVE_SOCKET +#cmakedefine HAVE_STRTOLL +#cmakedefine HAVE_STRTOI64 +#cmakedefine HAVE_SNPRINTF + +/* OpenSSL functions */ +#cmakedefine HAVE_EVP_AES_128_CTR + +/* Socket non-blocking support */ +#cmakedefine HAVE_O_NONBLOCK +#cmakedefine HAVE_FIONBIO +#cmakedefine HAVE_IOCTLSOCKET +#cmakedefine HAVE_IOCTLSOCKET_CASE +#cmakedefine HAVE_SO_NONBLOCK +#cmakedefine HAVE_DISABLED_NONBLOCKING + +/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible. + We provide a safe wrapper if snprintf not found */ +#ifndef HAVE_SNPRINTF +#include +#include +/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1 +* then assume cp is pointing to a null char and do nothing. Returns number +* number of chars placed in cp excluding the trailing null char. So for +* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len +* <= 0 the return value is 0 (and no chars are written to cp). */ +static int snprintf(char * cp, int cp_max_len, const char * fmt, ...) +{ + va_list args; + int n; + + if (cp_max_len < 2) + return 0; + va_start(args, fmt); + n = vsnprintf(cp, cp_max_len, fmt, args); + va_end(args); + return (n < cp_max_len) ? n : (cp_max_len - 1); +} + +#define HAVE_SNPRINTF +#endif diff --git a/libssh2/src/libssh2_priv.h b/libssh2/src/libssh2_priv.h new file mode 100644 index 000000000..b4296a221 --- /dev/null +++ b/libssh2/src/libssh2_priv.h @@ -0,0 +1,1067 @@ +/* Copyright (c) 2004-2008, 2010, Sara Golemon + * Copyright (c) 2009-2014 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBSSH2_PRIV_H +#define LIBSSH2_PRIV_H 1 + +#define LIBSSH2_LIBRARY +#include "libssh2_config.h" + +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#undef WIN32_LEAN_AND_MEAN +#endif + +#ifdef HAVE_WS2TCPIP_H +#include +#endif + +#include +#include + +/* The following CPP block should really only be in session.c and + packet.c. However, AIX have #define's for 'events' and 'revents' + and we are using those names in libssh2.h, so we need to include + the AIX headers first, to make sure all code is compiled with + consistent names of these fields. While arguable the best would to + change libssh2.h to use other names, that would break backwards + compatibility. For more information, see: + https://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html + https://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html +*/ +#ifdef HAVE_POLL +# include +#else +# if defined(HAVE_SELECT) && !defined(WIN32) +# ifdef HAVE_SYS_SELECT_H +# include +# else +# include +# include +# endif +# endif +#endif + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_INTTYPES_H +#include +#endif + +#include "libssh2.h" +#include "libssh2_publickey.h" +#include "libssh2_sftp.h" +#include "misc.h" /* for the linked list stuff */ + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#ifdef _MSC_VER +/* "inline" keyword is valid only with C++ engine! */ +#define inline __inline +#endif + +/* Provide iovec / writev on WIN32 platform. */ +#ifdef WIN32 + +struct iovec { + size_t iov_len; + void * iov_base; +}; + +static inline int writev(int sock, struct iovec *iov, int nvecs) +{ + DWORD ret; + if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) { + return ret; + } + return -1; +} + +#endif /* WIN32 */ + +#ifdef __OS400__ +/* Force parameter type. */ +#define send(s, b, l, f) send((s), (unsigned char *) (b), (l), (f)) +#endif + +#include "crypto.h" + +#ifdef HAVE_WINSOCK2_H + +#include +#include + +#endif + +/* RFC4253 section 6.1 Maximum Packet Length says: + * + * "All implementations MUST be able to process packets with + * uncompressed payload length of 32768 bytes or less and + * total packet size of 35000 bytes or less (including length, + * padding length, payload, padding, and MAC.)." + */ +#define MAX_SSH_PACKET_LEN 35000 +#define MAX_SHA_DIGEST_LEN SHA256_DIGEST_LENGTH + +#define LIBSSH2_ALLOC(session, count) \ + session->alloc((count), &(session)->abstract) +#define LIBSSH2_CALLOC(session, count) _libssh2_calloc(session, count) +#define LIBSSH2_REALLOC(session, ptr, count) \ + ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \ + session->alloc((count), &(session)->abstract)) +#define LIBSSH2_FREE(session, ptr) \ + session->free((ptr), &(session)->abstract) +#define LIBSSH2_IGNORE(session, data, datalen) \ + session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract) +#define LIBSSH2_DEBUG(session, always_display, message, message_len, \ + language, language_len) \ + session->ssh_msg_debug((session), (always_display), (message), \ + (message_len), (language), (language_len), \ + &(session)->abstract) +#define LIBSSH2_DISCONNECT(session, reason, message, message_len, \ + language, language_len) \ + session->ssh_msg_disconnect((session), (reason), (message), \ + (message_len), (language), (language_len), \ + &(session)->abstract) + +#define LIBSSH2_MACERROR(session, data, datalen) \ + session->macerror((session), (data), (datalen), &(session)->abstract) +#define LIBSSH2_X11_OPEN(channel, shost, sport) \ + channel->session->x11(((channel)->session), (channel), \ + (shost), (sport), (&(channel)->session->abstract)) + +#define LIBSSH2_CHANNEL_CLOSE(session, channel) \ + channel->close_cb((session), &(session)->abstract, \ + (channel), &(channel)->abstract) + +#define LIBSSH2_SEND_FD(session, fd, buffer, length, flags) \ + (session->send)(fd, buffer, length, flags, &session->abstract) +#define LIBSSH2_RECV_FD(session, fd, buffer, length, flags) \ + (session->recv)(fd, buffer, length, flags, &session->abstract) + +#define LIBSSH2_SEND(session, buffer, length, flags) \ + LIBSSH2_SEND_FD(session, session->socket_fd, buffer, length, flags) +#define LIBSSH2_RECV(session, buffer, length, flags) \ + LIBSSH2_RECV_FD(session, session->socket_fd, buffer, length, flags) + +typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD; +typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD; +typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD; +typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD; + +typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET; + +typedef enum +{ + libssh2_NB_state_idle = 0, + libssh2_NB_state_allocated, + libssh2_NB_state_created, + libssh2_NB_state_sent, + libssh2_NB_state_sent1, + libssh2_NB_state_sent2, + libssh2_NB_state_sent3, + libssh2_NB_state_sent4, + libssh2_NB_state_sent5, + libssh2_NB_state_sent6, + libssh2_NB_state_sent7, + libssh2_NB_state_jump1, + libssh2_NB_state_jump2, + libssh2_NB_state_jump3, + libssh2_NB_state_jump4, + libssh2_NB_state_jump5, + libssh2_NB_state_end +} libssh2_nonblocking_states; + +typedef struct packet_require_state_t +{ + libssh2_nonblocking_states state; + time_t start; +} packet_require_state_t; + +typedef struct packet_requirev_state_t +{ + time_t start; +} packet_requirev_state_t; + +typedef struct kmdhgGPshakex_state_t +{ + libssh2_nonblocking_states state; + unsigned char *e_packet; + unsigned char *s_packet; + unsigned char *tmp; + unsigned char h_sig_comp[MAX_SHA_DIGEST_LEN]; + unsigned char c; + size_t e_packet_len; + size_t s_packet_len; + size_t tmp_len; + _libssh2_bn_ctx *ctx; + _libssh2_bn *x; + _libssh2_bn *e; + _libssh2_bn *f; + _libssh2_bn *k; + unsigned char *s; + unsigned char *f_value; + unsigned char *k_value; + unsigned char *h_sig; + size_t f_value_len; + size_t k_value_len; + size_t h_sig_len; + void *exchange_hash; + packet_require_state_t req_state; + libssh2_nonblocking_states burn_state; +} kmdhgGPshakex_state_t; + +typedef struct key_exchange_state_low_t +{ + libssh2_nonblocking_states state; + packet_require_state_t req_state; + kmdhgGPshakex_state_t exchange_state; + _libssh2_bn *p; /* SSH2 defined value (p_value) */ + _libssh2_bn *g; /* SSH2 defined value (2) */ + unsigned char request[13]; + unsigned char *data; + size_t request_len; + size_t data_len; +} key_exchange_state_low_t; + +typedef struct key_exchange_state_t +{ + libssh2_nonblocking_states state; + packet_require_state_t req_state; + key_exchange_state_low_t key_state_low; + unsigned char *data; + size_t data_len; + unsigned char *oldlocal; + size_t oldlocal_len; +} key_exchange_state_t; + +#define FwdNotReq "Forward not requested" + +typedef struct packet_queue_listener_state_t +{ + libssh2_nonblocking_states state; + unsigned char packet[17 + (sizeof(FwdNotReq) - 1)]; + unsigned char *host; + unsigned char *shost; + uint32_t sender_channel; + uint32_t initial_window_size; + uint32_t packet_size; + uint32_t port; + uint32_t sport; + uint32_t host_len; + uint32_t shost_len; + LIBSSH2_CHANNEL *channel; +} packet_queue_listener_state_t; + +#define X11FwdUnAvil "X11 Forward Unavailable" + +typedef struct packet_x11_open_state_t +{ + libssh2_nonblocking_states state; + unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)]; + unsigned char *shost; + uint32_t sender_channel; + uint32_t initial_window_size; + uint32_t packet_size; + uint32_t sport; + uint32_t shost_len; + LIBSSH2_CHANNEL *channel; +} packet_x11_open_state_t; + +struct _LIBSSH2_PACKET +{ + struct list_node node; /* linked list header */ + + /* the raw unencrypted payload */ + unsigned char *data; + size_t data_len; + + /* Where to start reading data from, + * used for channel data that's been partially consumed */ + size_t data_head; +}; + +typedef struct _libssh2_channel_data +{ + /* Identifier */ + uint32_t id; + + /* Limits and restrictions */ + uint32_t window_size_initial, window_size, packet_size; + + /* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */ + char close, eof, extended_data_ignore_mode; +} libssh2_channel_data; + +struct _LIBSSH2_CHANNEL +{ + struct list_node node; + + unsigned char *channel_type; + unsigned channel_type_len; + + /* channel's program exit status */ + int exit_status; + + /* channel's program exit signal (without the SIG prefix) */ + char *exit_signal; + + libssh2_channel_data local, remote; + /* Amount of bytes to be refunded to receive window (but not yet sent) */ + uint32_t adjust_queue; + /* Data immediately available for reading */ + uint32_t read_avail; + + LIBSSH2_SESSION *session; + + void *abstract; + LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb)); + + /* State variables used in libssh2_channel_setenv_ex() */ + libssh2_nonblocking_states setenv_state; + unsigned char *setenv_packet; + size_t setenv_packet_len; + unsigned char setenv_local_channel[4]; + packet_requirev_state_t setenv_packet_requirev_state; + + /* State variables used in libssh2_channel_request_pty_ex() + libssh2_channel_request_pty_size_ex() */ + libssh2_nonblocking_states reqPTY_state; + unsigned char reqPTY_packet[41 + 256]; + size_t reqPTY_packet_len; + unsigned char reqPTY_local_channel[4]; + packet_requirev_state_t reqPTY_packet_requirev_state; + + /* State variables used in libssh2_channel_x11_req_ex() */ + libssh2_nonblocking_states reqX11_state; + unsigned char *reqX11_packet; + size_t reqX11_packet_len; + unsigned char reqX11_local_channel[4]; + packet_requirev_state_t reqX11_packet_requirev_state; + + /* State variables used in libssh2_channel_process_startup() */ + libssh2_nonblocking_states process_state; + unsigned char *process_packet; + size_t process_packet_len; + unsigned char process_local_channel[4]; + packet_requirev_state_t process_packet_requirev_state; + + /* State variables used in libssh2_channel_flush_ex() */ + libssh2_nonblocking_states flush_state; + size_t flush_refund_bytes; + size_t flush_flush_bytes; + + /* State variables used in libssh2_channel_receive_window_adjust() */ + libssh2_nonblocking_states adjust_state; + unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */ + + /* State variables used in libssh2_channel_read_ex() */ + libssh2_nonblocking_states read_state; + + uint32_t read_local_id; + + /* State variables used in libssh2_channel_write_ex() */ + libssh2_nonblocking_states write_state; + unsigned char write_packet[13]; + size_t write_packet_len; + size_t write_bufwrite; + + /* State variables used in libssh2_channel_close() */ + libssh2_nonblocking_states close_state; + unsigned char close_packet[5]; + + /* State variables used in libssh2_channel_wait_closedeof() */ + libssh2_nonblocking_states wait_eof_state; + + /* State variables used in libssh2_channel_wait_closed() */ + libssh2_nonblocking_states wait_closed_state; + + /* State variables used in libssh2_channel_free() */ + libssh2_nonblocking_states free_state; + + /* State variables used in libssh2_channel_handle_extended_data2() */ + libssh2_nonblocking_states extData2_state; + +}; + +struct _LIBSSH2_LISTENER +{ + struct list_node node; /* linked list header */ + + LIBSSH2_SESSION *session; + + char *host; + int port; + + /* a list of CHANNELs for this listener */ + struct list_head queue; + + int queue_size; + int queue_maxsize; + + /* State variables used in libssh2_channel_forward_cancel() */ + libssh2_nonblocking_states chanFwdCncl_state; + unsigned char *chanFwdCncl_data; + size_t chanFwdCncl_data_len; +}; + +typedef struct _libssh2_endpoint_data +{ + unsigned char *banner; + + unsigned char *kexinit; + size_t kexinit_len; + + const LIBSSH2_CRYPT_METHOD *crypt; + void *crypt_abstract; + + const struct _LIBSSH2_MAC_METHOD *mac; + uint32_t seqno; + void *mac_abstract; + + const LIBSSH2_COMP_METHOD *comp; + void *comp_abstract; + + /* Method Preferences -- NULL yields "load order" */ + char *crypt_prefs; + char *mac_prefs; + char *comp_prefs; + char *lang_prefs; +} libssh2_endpoint_data; + +#define PACKETBUFSIZE (1024*16) + +struct transportpacket +{ + /* ------------- for incoming data --------------- */ + unsigned char buf[PACKETBUFSIZE]; + unsigned char init[5]; /* first 5 bytes of the incoming data stream, + still encrypted */ + size_t writeidx; /* at what array index we do the next write into + the buffer */ + size_t readidx; /* at what array index we do the next read from + the buffer */ + uint32_t packet_length; /* the most recent packet_length as read from the + network data */ + uint8_t padding_length; /* the most recent padding_length as read from the + network data */ + size_t data_num; /* How much of the total package that has been read + so far. */ + size_t total_num; /* How much a total package is supposed to be, in + number of bytes. A full package is + packet_length + padding_length + 4 + + mac_length. */ + unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC() + area to which we write decrypted data */ + unsigned char *wptr; /* write pointer into the payload to where we + are currently writing decrypted data */ + + /* ------------- for outgoing data --------------- */ + unsigned char outbuf[MAX_SSH_PACKET_LEN]; /* area for the outgoing data */ + + int ototal_num; /* size of outbuf in number of bytes */ + const unsigned char *odata; /* original pointer to the data */ + size_t olen; /* original size of the data we stored in + outbuf */ + size_t osent; /* number of bytes already sent */ +}; + +struct _LIBSSH2_PUBLICKEY +{ + LIBSSH2_CHANNEL *channel; + uint32_t version; + + /* State variables used in libssh2_publickey_packet_receive() */ + libssh2_nonblocking_states receive_state; + unsigned char *receive_packet; + size_t receive_packet_len; + + /* State variables used in libssh2_publickey_add_ex() */ + libssh2_nonblocking_states add_state; + unsigned char *add_packet; + unsigned char *add_s; + + /* State variables used in libssh2_publickey_remove_ex() */ + libssh2_nonblocking_states remove_state; + unsigned char *remove_packet; + unsigned char *remove_s; + + /* State variables used in libssh2_publickey_list_fetch() */ + libssh2_nonblocking_states listFetch_state; + unsigned char *listFetch_s; + unsigned char listFetch_buffer[12]; + unsigned char *listFetch_data; + size_t listFetch_data_len; +}; + +#define LIBSSH2_SCP_RESPONSE_BUFLEN 256 + +struct flags { + int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */ + int compress; /* LIBSSH2_FLAG_COMPRESS */ +}; + +struct _LIBSSH2_SESSION +{ + /* Memory management callbacks */ + void *abstract; + LIBSSH2_ALLOC_FUNC((*alloc)); + LIBSSH2_REALLOC_FUNC((*realloc)); + LIBSSH2_FREE_FUNC((*free)); + + /* Other callbacks */ + LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore)); + LIBSSH2_DEBUG_FUNC((*ssh_msg_debug)); + LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect)); + LIBSSH2_MACERROR_FUNC((*macerror)); + LIBSSH2_X11_OPEN_FUNC((*x11)); + LIBSSH2_SEND_FUNC((*send)); + LIBSSH2_RECV_FUNC((*recv)); + + /* Method preferences -- NULL yields "load order" */ + char *kex_prefs; + char *hostkey_prefs; + + int state; + + /* Flag options */ + struct flags flag; + + /* Agreed Key Exchange Method */ + const LIBSSH2_KEX_METHOD *kex; + unsigned int burn_optimistic_kexinit:1; + + unsigned char *session_id; + uint32_t session_id_len; + + /* this is set to TRUE if a blocking API behavior is requested */ + int api_block_mode; + + /* Timeout used when blocking API behavior is active */ + long api_timeout; + + /* Server's public key */ + const LIBSSH2_HOSTKEY_METHOD *hostkey; + void *server_hostkey_abstract; + + /* Either set with libssh2_session_hostkey() (for server mode) + * Or read from server in (eg) KEXDH_INIT (for client mode) + */ + unsigned char *server_hostkey; + uint32_t server_hostkey_len; +#if LIBSSH2_MD5 + unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH]; + int server_hostkey_md5_valid; +#endif /* ! LIBSSH2_MD5 */ + unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH]; + int server_hostkey_sha1_valid; + + /* (remote as source of data -- packet_read ) */ + libssh2_endpoint_data remote; + + /* (local as source of data -- packet_write ) */ + libssh2_endpoint_data local; + + /* Inbound Data linked list -- Sometimes the packet that comes in isn't the + packet we're ready for */ + struct list_head packets; + + /* Active connection channels */ + struct list_head channels; + + uint32_t next_channel; + + struct list_head listeners; /* list of LIBSSH2_LISTENER structs */ + + /* Actual I/O socket */ + libssh2_socket_t socket_fd; + int socket_state; + int socket_block_directions; + int socket_prev_blockstate; /* stores the state of the socket blockiness + when libssh2_session_startup() is called */ + + /* Error tracking */ + const char *err_msg; + int err_code; + int err_flags; + + /* struct members for packet-level reading */ + struct transportpacket packet; +#ifdef LIBSSH2DEBUG + int showmask; /* what debug/trace messages to display */ + libssh2_trace_handler_func tracehandler; /* callback to display trace messages */ + void* tracehandler_context; /* context for the trace handler */ +#endif + + /* State variables used in libssh2_banner_send() */ + libssh2_nonblocking_states banner_TxRx_state; + char banner_TxRx_banner[256]; + ssize_t banner_TxRx_total_send; + + /* State variables used in libssh2_kexinit() */ + libssh2_nonblocking_states kexinit_state; + unsigned char *kexinit_data; + size_t kexinit_data_len; + + /* State variables used in libssh2_session_startup() */ + libssh2_nonblocking_states startup_state; + unsigned char *startup_data; + size_t startup_data_len; + unsigned char startup_service[sizeof("ssh-userauth") + 5 - 1]; + size_t startup_service_length; + packet_require_state_t startup_req_state; + key_exchange_state_t startup_key_state; + + /* State variables used in libssh2_session_free() */ + libssh2_nonblocking_states free_state; + + /* State variables used in libssh2_session_disconnect_ex() */ + libssh2_nonblocking_states disconnect_state; + unsigned char disconnect_data[256 + 13]; + size_t disconnect_data_len; + + /* State variables used in libssh2_packet_read() */ + libssh2_nonblocking_states readPack_state; + int readPack_encrypted; + + /* State variables used in libssh2_userauth_list() */ + libssh2_nonblocking_states userauth_list_state; + unsigned char *userauth_list_data; + size_t userauth_list_data_len; + packet_requirev_state_t userauth_list_packet_requirev_state; + + /* State variables used in libssh2_userauth_password_ex() */ + libssh2_nonblocking_states userauth_pswd_state; + unsigned char *userauth_pswd_data; + unsigned char userauth_pswd_data0; + size_t userauth_pswd_data_len; + char *userauth_pswd_newpw; + int userauth_pswd_newpw_len; + packet_requirev_state_t userauth_pswd_packet_requirev_state; + + /* State variables used in libssh2_userauth_hostbased_fromfile_ex() */ + libssh2_nonblocking_states userauth_host_state; + unsigned char *userauth_host_data; + size_t userauth_host_data_len; + unsigned char *userauth_host_packet; + size_t userauth_host_packet_len; + unsigned char *userauth_host_method; + size_t userauth_host_method_len; + unsigned char *userauth_host_s; + packet_requirev_state_t userauth_host_packet_requirev_state; + + /* State variables used in libssh2_userauth_publickey_fromfile_ex() */ + libssh2_nonblocking_states userauth_pblc_state; + unsigned char *userauth_pblc_data; + size_t userauth_pblc_data_len; + unsigned char *userauth_pblc_packet; + size_t userauth_pblc_packet_len; + unsigned char *userauth_pblc_method; + size_t userauth_pblc_method_len; + unsigned char *userauth_pblc_s; + unsigned char *userauth_pblc_b; + packet_requirev_state_t userauth_pblc_packet_requirev_state; + + /* State variables used in libssh2_userauth_keyboard_interactive_ex() */ + libssh2_nonblocking_states userauth_kybd_state; + unsigned char *userauth_kybd_data; + size_t userauth_kybd_data_len; + unsigned char *userauth_kybd_packet; + size_t userauth_kybd_packet_len; + unsigned int userauth_kybd_auth_name_len; + char *userauth_kybd_auth_name; + unsigned userauth_kybd_auth_instruction_len; + char *userauth_kybd_auth_instruction; + unsigned int userauth_kybd_num_prompts; + int userauth_kybd_auth_failure; + LIBSSH2_USERAUTH_KBDINT_PROMPT *userauth_kybd_prompts; + LIBSSH2_USERAUTH_KBDINT_RESPONSE *userauth_kybd_responses; + packet_requirev_state_t userauth_kybd_packet_requirev_state; + + /* State variables used in libssh2_channel_open_ex() */ + libssh2_nonblocking_states open_state; + packet_requirev_state_t open_packet_requirev_state; + LIBSSH2_CHANNEL *open_channel; + unsigned char *open_packet; + size_t open_packet_len; + unsigned char *open_data; + size_t open_data_len; + uint32_t open_local_channel; + + /* State variables used in libssh2_channel_direct_tcpip_ex() */ + libssh2_nonblocking_states direct_state; + unsigned char *direct_message; + size_t direct_host_len; + size_t direct_shost_len; + size_t direct_message_len; + + /* State variables used in libssh2_channel_forward_listen_ex() */ + libssh2_nonblocking_states fwdLstn_state; + unsigned char *fwdLstn_packet; + uint32_t fwdLstn_host_len; + uint32_t fwdLstn_packet_len; + packet_requirev_state_t fwdLstn_packet_requirev_state; + + /* State variables used in libssh2_publickey_init() */ + libssh2_nonblocking_states pkeyInit_state; + LIBSSH2_PUBLICKEY *pkeyInit_pkey; + LIBSSH2_CHANNEL *pkeyInit_channel; + unsigned char *pkeyInit_data; + size_t pkeyInit_data_len; + /* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */ + unsigned char pkeyInit_buffer[19]; + size_t pkeyInit_buffer_sent; /* how much of buffer that has been sent */ + + /* State variables used in libssh2_packet_add() */ + libssh2_nonblocking_states packAdd_state; + LIBSSH2_CHANNEL *packAdd_channelp; /* keeper of the channel during EAGAIN + states */ + packet_queue_listener_state_t packAdd_Qlstn_state; + packet_x11_open_state_t packAdd_x11open_state; + + /* State variables used in fullpacket() */ + libssh2_nonblocking_states fullpacket_state; + int fullpacket_macstate; + size_t fullpacket_payload_len; + int fullpacket_packet_type; + + /* State variables used in libssh2_sftp_init() */ + libssh2_nonblocking_states sftpInit_state; + LIBSSH2_SFTP *sftpInit_sftp; + LIBSSH2_CHANNEL *sftpInit_channel; + unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id} + + version_id(4) */ + int sftpInit_sent; /* number of bytes from the buffer that have been + sent */ + + /* State variables used in libssh2_scp_recv() / libssh_scp_recv2() */ + libssh2_nonblocking_states scpRecv_state; + unsigned char *scpRecv_command; + size_t scpRecv_command_len; + unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + size_t scpRecv_response_len; + long scpRecv_mode; +#if defined(HAVE_LONGLONG) && defined(HAVE_STRTOLL) + /* we have the type and we can parse such numbers */ + long long scpRecv_size; +#define scpsize_strtol strtoll +#elif defined(HAVE_STRTOI64) + __int64 scpRecv_size; +#define scpsize_strtol _strtoi64 +#else + long scpRecv_size; +#define scpsize_strtol strtol +#endif + long scpRecv_mtime; + long scpRecv_atime; + LIBSSH2_CHANNEL *scpRecv_channel; + + /* State variables used in libssh2_scp_send_ex() */ + libssh2_nonblocking_states scpSend_state; + unsigned char *scpSend_command; + size_t scpSend_command_len; + unsigned char scpSend_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + size_t scpSend_response_len; + LIBSSH2_CHANNEL *scpSend_channel; + + /* Keepalive variables used by keepalive.c. */ + int keepalive_interval; + int keepalive_want_reply; + time_t keepalive_last_sent; +}; + +/* session.state bits */ +#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001 +#define LIBSSH2_STATE_NEWKEYS 0x00000002 +#define LIBSSH2_STATE_AUTHENTICATED 0x00000004 +#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008 + +/* session.flag helpers */ +#ifdef MSG_NOSIGNAL +#define LIBSSH2_SOCKET_SEND_FLAGS(session) \ + (((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL) +#define LIBSSH2_SOCKET_RECV_FLAGS(session) \ + (((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL) +#else +/* If MSG_NOSIGNAL isn't defined we're SOL on blocking SIGPIPE */ +#define LIBSSH2_SOCKET_SEND_FLAGS(session) 0 +#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0 +#endif + +/* --------- */ + +/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional + methods via .so/.dll */ + +struct _LIBSSH2_KEX_METHOD +{ + const char *name; + + /* Key exchange, populates session->* and returns 0 on success, non-0 on error */ + int (*exchange_keys) (LIBSSH2_SESSION * session, + key_exchange_state_low_t * key_state); + + long flags; +}; + +struct _LIBSSH2_HOSTKEY_METHOD +{ + const char *name; + unsigned long hash_len; + + int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data, + size_t hostkey_data_len, void **abstract); + int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile, + unsigned const char *passphrase, void **abstract); + int (*initPEMFromMemory) (LIBSSH2_SESSION * session, + const char *privkeyfiledata, size_t privkeyfiledata_len, + unsigned const char *passphrase, void **abstract); + int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig, + size_t sig_len, const unsigned char *m, + size_t m_len, void **abstract); + int (*signv) (LIBSSH2_SESSION * session, unsigned char **signature, + size_t *signature_len, int veccount, + const struct iovec datavec[], void **abstract); + int (*encrypt) (LIBSSH2_SESSION * session, unsigned char **dst, + size_t *dst_len, const unsigned char *src, + size_t src_len, void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, void **abstract); +}; + +struct _LIBSSH2_CRYPT_METHOD +{ + const char *name; + + int blocksize; + + /* iv and key sizes (-1 for variable length) */ + int iv_len; + int secret_len; + + long flags; + + int (*init) (LIBSSH2_SESSION * session, + const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv, + int *free_iv, unsigned char *secret, int *free_secret, + int encrypt, void **abstract); + int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block, + size_t blocksize, void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, void **abstract); + + _libssh2_cipher_type(algo); +}; + +struct _LIBSSH2_COMP_METHOD +{ + const char *name; + int compress; /* 1 if it does compress, 0 if it doesn't */ + int use_in_auth; /* 1 if compression should be used in userauth */ + int (*init) (LIBSSH2_SESSION *session, int compress, void **abstract); + int (*comp) (LIBSSH2_SESSION *session, + unsigned char *dest, + size_t *dest_len, + const unsigned char *src, + size_t src_len, + void **abstract); + int (*decomp) (LIBSSH2_SESSION *session, + unsigned char **dest, + size_t *dest_len, + size_t payload_limit, + const unsigned char *src, + size_t src_len, + void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, int compress, void **abstract); +}; + +#ifdef LIBSSH2DEBUG +void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, + ...); +#else +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__GNUC__) +/* C99 supported and also by older GCC */ +#define _libssh2_debug(x,y,z,...) do {} while (0) +#else +/* no gcc and not C99, do static and hopefully inline */ +static inline void +_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...) +{ + (void)session; + (void)context; + (void)format; +} +#endif +#endif + +#define LIBSSH2_SOCKET_UNKNOWN 1 +#define LIBSSH2_SOCKET_CONNECTED 0 +#define LIBSSH2_SOCKET_DISCONNECTED -1 + +/* Initial packet state, prior to MAC check */ +#define LIBSSH2_MAC_UNCONFIRMED 1 +/* When MAC type is "none" (proto initiation phase) all packets are deemed "confirmed" */ +#define LIBSSH2_MAC_CONFIRMED 0 +/* Something very bad is going on */ +#define LIBSSH2_MAC_INVALID -1 + +/* Flags for _libssh2_error_flags */ +/* Error message is allocated on the heap */ +#define LIBSSH2_ERR_FLAG_DUP 1 + +/* SSH Packet Types -- Defined by internet draft */ +/* Transport Layer */ +#define SSH_MSG_DISCONNECT 1 +#define SSH_MSG_IGNORE 2 +#define SSH_MSG_UNIMPLEMENTED 3 +#define SSH_MSG_DEBUG 4 +#define SSH_MSG_SERVICE_REQUEST 5 +#define SSH_MSG_SERVICE_ACCEPT 6 + +#define SSH_MSG_KEXINIT 20 +#define SSH_MSG_NEWKEYS 21 + +/* diffie-hellman-group1-sha1 */ +#define SSH_MSG_KEXDH_INIT 30 +#define SSH_MSG_KEXDH_REPLY 31 + +/* diffie-hellman-group-exchange-sha1 and diffie-hellman-group-exchange-sha256 */ +#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30 +#define SSH_MSG_KEX_DH_GEX_REQUEST 34 +#define SSH_MSG_KEX_DH_GEX_GROUP 31 +#define SSH_MSG_KEX_DH_GEX_INIT 32 +#define SSH_MSG_KEX_DH_GEX_REPLY 33 + +/* User Authentication */ +#define SSH_MSG_USERAUTH_REQUEST 50 +#define SSH_MSG_USERAUTH_FAILURE 51 +#define SSH_MSG_USERAUTH_SUCCESS 52 +#define SSH_MSG_USERAUTH_BANNER 53 + +/* "public key" method */ +#define SSH_MSG_USERAUTH_PK_OK 60 +/* "password" method */ +#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60 +/* "keyboard-interactive" method */ +#define SSH_MSG_USERAUTH_INFO_REQUEST 60 +#define SSH_MSG_USERAUTH_INFO_RESPONSE 61 + +/* Channels */ +#define SSH_MSG_GLOBAL_REQUEST 80 +#define SSH_MSG_REQUEST_SUCCESS 81 +#define SSH_MSG_REQUEST_FAILURE 82 + +#define SSH_MSG_CHANNEL_OPEN 90 +#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91 +#define SSH_MSG_CHANNEL_OPEN_FAILURE 92 +#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93 +#define SSH_MSG_CHANNEL_DATA 94 +#define SSH_MSG_CHANNEL_EXTENDED_DATA 95 +#define SSH_MSG_CHANNEL_EOF 96 +#define SSH_MSG_CHANNEL_CLOSE 97 +#define SSH_MSG_CHANNEL_REQUEST 98 +#define SSH_MSG_CHANNEL_SUCCESS 99 +#define SSH_MSG_CHANNEL_FAILURE 100 + +/* Error codes returned in SSH_MSG_CHANNEL_OPEN_FAILURE message + (see RFC4254) */ +#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1 +#define SSH_OPEN_CONNECT_FAILED 2 +#define SSH_OPEN_UNKNOWN_CHANNELTYPE 3 +#define SSH_OPEN_RESOURCE_SHORTAGE 4 + +ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer, + size_t length, int flags, void **abstract); +ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, + size_t length, int flags, void **abstract); + +#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when + waiting for more data to arrive */ + + +int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + key_exchange_state_t * state); + +/* Let crypt.c/hostkey.c expose their method structs */ +const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void); +const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void); + +/* pem.c */ +int _libssh2_pem_parse(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + FILE * fp, unsigned char **data, unsigned int *datalen); +int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + const char *filedata, size_t filedata_len, + unsigned char **data, unsigned int *datalen); +int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen); +int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen, + unsigned char **i, unsigned int *ilen); + +/* global.c */ +void _libssh2_init_if_needed (void); + + +#define ARRAY_SIZE(a) (sizeof ((a)) / sizeof ((a)[0])) + +/* define to output the libssh2_int64_t type in a *printf() */ +#if defined( __BORLANDC__ ) || defined( _MSC_VER ) || defined( __MINGW32__ ) +#define LIBSSH2_INT64_T_FORMAT "I64d" +#else +#define LIBSSH2_INT64_T_FORMAT "lld" +#endif + +#endif /* LIBSSH2_H */ diff --git a/libssh2/src/mac.c b/libssh2/src/mac.c new file mode 100644 index 000000000..5ec26eb3b --- /dev/null +++ b/libssh2/src/mac.c @@ -0,0 +1,414 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "mac.h" + +#ifdef LIBSSH2_MAC_NONE +/* mac_none_MAC + * Minimalist MAC: No MAC + */ +static int +mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf, + uint32_t seqno, const unsigned char *packet, + uint32_t packet_len, const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + return 0; +} + + + + +static LIBSSH2_MAC_METHOD mac_method_none = { + "none", + 0, + 0, + NULL, + mac_none_MAC, + NULL +}; +#endif /* LIBSSH2_MAC_NONE */ + +/* mac_method_common_init + * Initialize simple mac methods + */ +static int +mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key, + int *free_key, void **abstract) +{ + *abstract = key; + *free_key = 0; + (void) session; + + return 0; +} + + + +/* mac_method_common_dtor + * Cleanup simple mac methods + */ +static int +mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + if (*abstract) { + LIBSSH2_FREE(session, *abstract); + } + *abstract = NULL; + + return 0; +} + + + +#if LIBSSH2_HMAC_SHA512 +/* mac_method_hmac_sha512_hash + * Calculate hash using full sha512 value + */ +static int +mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha512_init(&ctx, *abstract, 64); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = { + "hmac-sha2-512", + 64, + 64, + mac_method_common_init, + mac_method_hmac_sha2_512_hash, + mac_method_common_dtor, +}; +#endif + + + +#if LIBSSH2_HMAC_SHA256 +/* mac_method_hmac_sha256_hash + * Calculate hash using full sha256 value + */ +static int +mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha256_init(&ctx, *abstract, 32); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = { + "hmac-sha2-256", + 32, + 32, + mac_method_common_init, + mac_method_hmac_sha2_256_hash, + mac_method_common_dtor, +}; +#endif + + + + +/* mac_method_hmac_sha1_hash + * Calculate hash using full sha1 value + */ +static int +mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha1_init(&ctx, *abstract, 20); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = { + "hmac-sha1", + 20, + 20, + mac_method_common_init, + mac_method_hmac_sha1_hash, + mac_method_common_dtor, +}; + +/* mac_method_hmac_sha1_96_hash + * Calculate hash using first 96 bits of sha1 value + */ +static int +mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + unsigned char temp[SHA_DIGEST_LENGTH]; + + mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, + addtl, addtl_len, abstract); + memcpy(buf, (char *) temp, 96 / 8); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = { + "hmac-sha1-96", + 12, + 20, + mac_method_common_init, + mac_method_hmac_sha1_96_hash, + mac_method_common_dtor, +}; + +#if LIBSSH2_MD5 +/* mac_method_hmac_md5_hash + * Calculate hash using full md5 value + */ +static int +mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf, + uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_md5_init(&ctx, *abstract, 16); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = { + "hmac-md5", + 16, + 16, + mac_method_common_init, + mac_method_hmac_md5_hash, + mac_method_common_dtor, +}; + +/* mac_method_hmac_md5_96_hash + * Calculate hash using first 96 bits of md5 value + */ +static int +mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + unsigned char temp[MD5_DIGEST_LENGTH]; + mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, + addtl, addtl_len, abstract); + memcpy(buf, (char *) temp, 96 / 8); + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = { + "hmac-md5-96", + 12, + 16, + mac_method_common_init, + mac_method_hmac_md5_96_hash, + mac_method_common_dtor, +}; +#endif /* LIBSSH2_MD5 */ + +#if LIBSSH2_HMAC_RIPEMD +/* mac_method_hmac_ripemd160_hash + * Calculate hash using ripemd160 value + */ +static int +mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, + void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = { + "hmac-ripemd160", + 20, + 20, + mac_method_common_init, + mac_method_hmac_ripemd160_hash, + mac_method_common_dtor, +}; + +static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = { + "hmac-ripemd160@openssh.com", + 20, + 20, + mac_method_common_init, + mac_method_hmac_ripemd160_hash, + mac_method_common_dtor, +}; +#endif /* LIBSSH2_HMAC_RIPEMD */ + +static const LIBSSH2_MAC_METHOD *mac_methods[] = { +#if LIBSSH2_HMAC_SHA256 + &mac_method_hmac_sha2_256, +#endif +#if LIBSSH2_HMAC_SHA512 + &mac_method_hmac_sha2_512, +#endif + &mac_method_hmac_sha1, + &mac_method_hmac_sha1_96, +#if LIBSSH2_MD5 + &mac_method_hmac_md5, + &mac_method_hmac_md5_96, +#endif +#if LIBSSH2_HMAC_RIPEMD + &mac_method_hmac_ripemd160, + &mac_method_hmac_ripemd160_openssh_com, +#endif /* LIBSSH2_HMAC_RIPEMD */ +#ifdef LIBSSH2_MAC_NONE + &mac_method_none, +#endif /* LIBSSH2_MAC_NONE */ + NULL +}; + +const LIBSSH2_MAC_METHOD ** +_libssh2_mac_methods(void) +{ + return mac_methods; +} diff --git a/libssh2/src/mac.h b/libssh2/src/mac.h new file mode 100644 index 000000000..66d3e6101 --- /dev/null +++ b/libssh2/src/mac.h @@ -0,0 +1,67 @@ +#ifndef __LIBSSH2_MAC_H +#define __LIBSSH2_MAC_H + +/* Copyright (C) 2009-2010 by Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" + +struct _LIBSSH2_MAC_METHOD +{ + const char *name; + + /* The length of a given MAC packet */ + int mac_len; + + /* integrity key length */ + int key_len; + + /* Message Authentication Code Hashing algo */ + int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key, + void **abstract); + int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf, + uint32_t seqno, const unsigned char *packet, + uint32_t packet_len, const unsigned char *addtl, + uint32_t addtl_len, void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, void **abstract); +}; + +typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD; + +const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void); + +#endif /* __LIBSSH2_MAC_H */ diff --git a/libssh2/src/mbedtls.c b/libssh2/src/mbedtls.c new file mode 100644 index 000000000..1d181e18f --- /dev/null +++ b/libssh2/src/mbedtls.c @@ -0,0 +1,606 @@ +#include "libssh2_priv.h" + +#ifdef LIBSSH2_MBEDTLS /* compile only if we build with mbedtls */ + +/*******************************************************************/ +/* + * mbedTLS backend: Generic functions + */ + +void +_libssh2_mbedtls_init(void) +{ + int ret; + + mbedtls_entropy_init(&_libssh2_mbedtls_entropy); + mbedtls_ctr_drbg_init(&_libssh2_mbedtls_ctr_drbg); + + ret = mbedtls_ctr_drbg_seed(&_libssh2_mbedtls_ctr_drbg, + mbedtls_entropy_func, + &_libssh2_mbedtls_entropy, NULL, 0); + if (ret != 0) + mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg); +} + +void +_libssh2_mbedtls_free(void) +{ + mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg); + mbedtls_entropy_free(&_libssh2_mbedtls_entropy); +} + +int +_libssh2_mbedtls_random(unsigned char *buf, int len) +{ + int ret; + ret = mbedtls_ctr_drbg_random(&_libssh2_mbedtls_ctr_drbg, buf, len); + return ret == 0 ? 0 : -1; +} + +static void +_libssh2_mbedtls_safe_free(void *buf, int len) +{ +#ifndef LIBSSH2_CLEAR_MEMORY + (void)len; +#endif + + if (!buf) + return; + +#ifdef LIBSSH2_CLEAR_MEMORY + if (len > 0) + memset(buf, 0, len); +#endif + + mbedtls_free(buf); +} + +int +_libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt) +{ + const mbedtls_cipher_info_t *cipher_info; + int ret, op; + + if (!ctx) + return -1; + + op = encrypt == 0 ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT; + + cipher_info = mbedtls_cipher_info_from_type(algo); + if(!cipher_info) + return -1; + + mbedtls_cipher_init(ctx); + ret = mbedtls_cipher_setup(ctx, cipher_info); + if(!ret) + ret = mbedtls_cipher_setkey(ctx, secret, cipher_info->key_bitlen, op); + + if(!ret) + ret = mbedtls_cipher_set_iv(ctx, iv, cipher_info->iv_size); + + return ret == 0 ? 0 : -1; +} + +int +_libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block, + size_t blocklen) +{ + int ret; + unsigned char *output; + size_t osize, olen, finish_olen; + + (void) encrypt; + (void) algo; + + osize = blocklen+mbedtls_cipher_get_block_size(ctx); + + output = (unsigned char *)mbedtls_calloc(osize, sizeof(char)); + if(output) + { + ret = mbedtls_cipher_reset(ctx); + + if(!ret) + ret = mbedtls_cipher_update(ctx, block, blocklen, output, &olen); + + if(!ret) + ret = mbedtls_cipher_finish(ctx, output + olen, &finish_olen); + + if (!ret) { + olen += finish_olen; + memcpy(block, output, olen); + } + + _libssh2_mbedtls_safe_free(output, osize); + } + else + ret = -1; + + return ret == 0 ? 0 : -1; +} + +void +_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx) +{ + mbedtls_cipher_free(ctx); +} + + +int +_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, + mbedtls_md_type_t mdtype, + const unsigned char *key, unsigned long keylen) +{ + const mbedtls_md_info_t *md_info; + int ret, hmac; + + md_info = mbedtls_md_info_from_type(mdtype); + if(!md_info) + return 0; + + hmac = key == NULL ? 0 : 1; + + mbedtls_md_init(ctx); + ret = mbedtls_md_setup(ctx, md_info, hmac); + if (!ret){ + if (hmac) + ret = mbedtls_md_hmac_starts(ctx, key, keylen); + else + ret = mbedtls_md_starts(ctx); + } + + return ret == 0 ? 1 : 0; +} + +int +_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash) +{ + int ret; + + ret = mbedtls_md_finish(ctx, hash); + mbedtls_md_free(ctx); + + return ret == 0 ? 0 : -1; +} + +int +_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, + mbedtls_md_type_t mdtype, unsigned char *hash) +{ + const mbedtls_md_info_t *md_info; + int ret; + + md_info = mbedtls_md_info_from_type(mdtype); + if(!md_info) + return 0; + + ret = mbedtls_md(md_info, data, datalen, hash); + + return ret == 0 ? 0 : -1; +} + +/*******************************************************************/ +/* + * mbedTLS backend: BigNumber functions + */ + +_libssh2_bn * +_libssh2_mbedtls_bignum_init(void) +{ + _libssh2_bn *bignum; + + bignum = (_libssh2_bn *)mbedtls_calloc(1, sizeof(_libssh2_bn)); + if (bignum) { + mbedtls_mpi_init(bignum); + } + + return bignum; +} + +int +_libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom) +{ + size_t len; + int err; + int i; + + if (!bn || bits <= 0) + return -1; + + len = (bits + 7) >> 3; + err = mbedtls_mpi_fill_random(bn, len, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg); + if (err) + return -1; + + /* Zero unsued bits above the most significant bit*/ + for(i=len*8-1;bits<=i;--i) { + err = mbedtls_mpi_set_bit(bn, i, 0); + if (err) + return -1; + } + + /* If `top` is -1, the most significant bit of the random number can be zero. + If top is 0, the most significant bit of the random number is set to 1, + and if top is 1, the two most significant bits of the number will be set + to 1, so that the product of two such random numbers will always have 2*bits length. + */ + for(i=0;i<=top;++i) { + err = mbedtls_mpi_set_bit(bn, bits-i-1, 1); + if (err) + return -1; + } + + /* make odd by setting first bit in least significant byte */ + if (bottom) { + err = mbedtls_mpi_set_bit(bn, 0, 1); + if (err) + return -1; + } + + return 0; +} + + +/*******************************************************************/ +/* + * mbedTLS backend: RSA functions + */ + +int +_libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen) +{ + int ret; + libssh2_rsa_ctx *ctx; + + ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); + if (ctx != NULL) { + mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0); + } + else + return -1; + + if( (ret = mbedtls_mpi_read_binary(&(ctx->E), edata, elen) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->N), ndata, nlen) ) != 0 ) + { + ret = -1; + } + + if (!ret) + { + ctx->len = mbedtls_mpi_size(&(ctx->N)); + } + + if (!ret && ddata) + { + if( (ret = mbedtls_mpi_read_binary(&(ctx->D) , ddata, dlen) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->P) , pdata, plen) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->Q) , qdata, qlen) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->DP), e1data, e1len) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->DQ), e2data, e2len) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->QP), coeffdata, coefflen) ) != 0 ) + { + ret = -1; + } + ret = mbedtls_rsa_check_privkey(ctx); + } + else if (!ret) + { + ret = mbedtls_rsa_check_pubkey(ctx); + } + + if (ret && ctx) { + _libssh2_mbedtls_rsa_free(ctx); + ctx = NULL; + } + *rsa = ctx; + return ret; +} + +int +_libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase) +{ + int ret; + mbedtls_pk_context pkey; + + *rsa = (libssh2_rsa_ctx *) LIBSSH2_ALLOC(session, sizeof(libssh2_rsa_ctx)); + if (*rsa == NULL) + return -1; + + mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0); + mbedtls_pk_init(&pkey); + + ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase); + if( ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) + { + mbedtls_pk_free(&pkey); + mbedtls_rsa_free(*rsa); + LIBSSH2_FREE(session, *rsa); + *rsa = NULL; + return -1; + } + + mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(pkey); + mbedtls_rsa_copy(*rsa, pk_rsa); + mbedtls_pk_free(&pkey); + + return 0; +} + +int +_libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ + int ret; + mbedtls_pk_context pkey; + + *rsa = (libssh2_rsa_ctx *) mbedtls_calloc( 1, sizeof( libssh2_rsa_ctx ) ); + if (*rsa == NULL) + return -1; + + mbedtls_pk_init(&pkey); + + ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata, + filedata_len, NULL, 0); + if( ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) + { + mbedtls_pk_free(&pkey); + mbedtls_rsa_free(*rsa); + LIBSSH2_FREE(session, *rsa); + *rsa = NULL; + return -1; + } + + mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(pkey); + mbedtls_rsa_copy(*rsa, pk_rsa); + mbedtls_pk_free(&pkey); + + return 0; +} + +int +_libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + int ret; + + ret = _libssh2_mbedtls_hash(m, m_len, MBEDTLS_MD_SHA1, hash); + if(ret) + return -1; /* failure */ + + ret = mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, + MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH, hash, sig); + + return (ret == 0) ? 0 : -1; +} + +int +_libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len) +{ + int ret; + unsigned char *sig; + unsigned int sig_len; + + (void)hash_len; + + sig_len = rsa->len; + sig = LIBSSH2_ALLOC(session, sig_len); + if (!sig) { + return -1; + } + + ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, + MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH, + hash, sig); + if (ret) { + LIBSSH2_FREE(session, sig); + return -1; + } + + *signature = sig; + *signature_len = sig_len; + + return (ret == 0) ? 0 : -1; +} + +void +_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *ctx) +{ + mbedtls_rsa_free(ctx); + mbedtls_free(ctx); +} + +static unsigned char * +gen_publickey_from_rsa(LIBSSH2_SESSION *session, + mbedtls_rsa_context *rsa, + size_t *keylen) +{ + int e_bytes, n_bytes; + unsigned long len; + unsigned char* key; + unsigned char* p; + + e_bytes = mbedtls_mpi_size(&rsa->E); + n_bytes = mbedtls_mpi_size(&rsa->N); + + /* Key form is "ssh-rsa" + e + n. */ + len = 4 + 7 + 4 + e_bytes + 4 + n_bytes; + + key = LIBSSH2_ALLOC(session, len); + if (!key) { + return NULL; + } + + /* Process key encoding. */ + p = key; + + _libssh2_htonu32(p, 7); /* Key type. */ + p += 4; + memcpy(p, "ssh-rsa", 7); + p += 7; + + _libssh2_htonu32(p, e_bytes); + p += 4; + mbedtls_mpi_write_binary(&rsa->E, p, e_bytes); + + _libssh2_htonu32(p, n_bytes); + p += 4; + mbedtls_mpi_write_binary(&rsa->N, p, n_bytes); + + *keylen = (size_t)(p - key); + return key; +} + +static int +_libssh2_mbedtls_pub_priv_key(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + mbedtls_pk_context *pkey) +{ + unsigned char *key = NULL, *mth = NULL; + size_t keylen = 0, mthlen = 0; + int ret; + + if( mbedtls_pk_get_type(pkey) != MBEDTLS_PK_RSA ) + { + mbedtls_pk_free(pkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Key type not supported"); + } + + // write method + mthlen = 7; + mth = LIBSSH2_ALLOC(session, mthlen); + if (mth) { + memcpy(mth, "ssh-rsa", mthlen); + } else { + ret = -1; + } + + mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pkey); + key = gen_publickey_from_rsa(session, rsa, &keylen); + if (key == NULL) { + ret = -1; + } + + // write output + if (ret) { + if (mth) + LIBSSH2_FREE(session, mth); + if (key) + LIBSSH2_FREE(session, key); + } else { + *method = mth; + *method_len = mthlen; + *pubkeydata = key; + *pubkeydata_len = keylen; + } + + return ret; +} + +int +_libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ + mbedtls_pk_context pkey; + char buf[1024]; + int ret; + + mbedtls_pk_init(&pkey); + ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase); + if( ret != 0 ) + { + mbedtls_strerror(ret, (char *)buf, sizeof(buf)); + mbedtls_pk_free(&pkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); + } + + ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len, + pubkeydata, pubkeydata_len, &pkey); + + mbedtls_pk_free(&pkey); + + return ret; +} + +int +_libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + mbedtls_pk_context pkey; + char buf[1024]; + int ret; + + mbedtls_pk_init(&pkey); + ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)privatekeydata, + privatekeydata_len, NULL, 0); + if( ret != 0 ) + { + mbedtls_strerror(ret, (char *)buf, sizeof(buf)); + mbedtls_pk_free(&pkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); + } + + ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len, + pubkeydata, pubkeydata_len, &pkey); + + mbedtls_pk_free(&pkey); + + return ret; +} + +void _libssh2_init_aes_ctr(void) +{ + /* no implementation */ +} +#endif /* LIBSSH2_MBEDTLS */ diff --git a/libssh2/src/mbedtls.h b/libssh2/src/mbedtls.h new file mode 100644 index 000000000..248583ed3 --- /dev/null +++ b/libssh2/src/mbedtls.h @@ -0,0 +1,371 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define which features are supported. */ +#define LIBSSH2_MD5 1 + +#define LIBSSH2_HMAC_RIPEMD 1 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#define LIBSSH2_AES 1 +#define LIBSSH2_AES_CTR 1 +#define LIBSSH2_BLOWFISH 1 +#define LIBSSH2_RC4 1 +#define LIBSSH2_CAST 0 +#define LIBSSH2_3DES 1 + +#define LIBSSH2_RSA 1 +#define LIBSSH2_DSA 0 + +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 +#define SHA512_DIGEST_LENGTH 64 + +/*******************************************************************/ +/* + * mbedTLS backend: Global context handles + */ + +mbedtls_entropy_context _libssh2_mbedtls_entropy; +mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg; + +/*******************************************************************/ +/* + * mbedTLS backend: Generic functions + */ + +#define libssh2_crypto_init() \ + _libssh2_mbedtls_init() +#define libssh2_crypto_exit() \ + _libssh2_mbedtls_free() + +#define _libssh2_random(buf, len) \ + _libssh2_mbedtls_random(buf, len) + +#define libssh2_prepare_iovec(vec, len) /* Empty. */ + + +/*******************************************************************/ +/* + * mbedTLS backend: HMAC functions + */ + +#define libssh2_hmac_ctx mbedtls_md_context_t + +#define libssh2_hmac_ctx_init(ctx) +#define libssh2_hmac_cleanup(pctx) \ + mbedtls_md_free(pctx) +#define libssh2_hmac_update(ctx, data, datalen) \ + mbedtls_md_hmac_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_hmac_final(ctx, hash) \ + mbedtls_md_hmac_finish(&ctx, hash) + +#define libssh2_hmac_sha1_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, key, keylen) +#define libssh2_hmac_md5_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, key, keylen) +#define libssh2_hmac_ripemd160_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_RIPEMD160, key, keylen) +#define libssh2_hmac_sha256_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, key, keylen) +#define libssh2_hmac_sha512_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, key, keylen) + + +/*******************************************************************/ +/* + * mbedTLS backend: SHA1 functions + */ + +#define libssh2_sha1_ctx mbedtls_md_context_t + +#define libssh2_sha1_init(pctx) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, NULL, 0) +#define libssh2_sha1_update(ctx, data, datalen) \ + mbedtls_md_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha1_final(ctx, hash) \ + _libssh2_mbedtls_hash_final(&ctx, hash) +#define libssh2_sha1(data, datalen, hash) \ + _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA1, hash) + +/*******************************************************************/ +/* + * mbedTLS backend: SHA256 functions + */ + +#define libssh2_sha256_ctx mbedtls_md_context_t + +#define libssh2_sha256_init(pctx) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, NULL, 0) +#define libssh2_sha256_update(ctx, data, datalen) \ + mbedtls_md_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha256_final(ctx, hash) \ + _libssh2_mbedtls_hash_final(&ctx, hash) +#define libssh2_sha256(data, datalen, hash) \ + _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash) + + +/*******************************************************************/ +/* + * mbedTLS backend: SHA512 functions + */ + +#define libssh2_sha512_ctx mbedtls_md_context_t + +#define libssh2_sha512_init(pctx) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, NULL, 0) +#define libssh2_sha512_update(ctx, data, datalen) \ + mbedtls_md_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha512_final(ctx, hash) \ + _libssh2_mbedtls_hash_final(&ctx, hash) +#define libssh2_sha512(data, datalen, hash) \ + _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA512, hash) + + +/*******************************************************************/ +/* + * mbedTLS backend: MD5 functions + */ + +#define libssh2_md5_ctx mbedtls_md_context_t + +#define libssh2_md5_init(pctx) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, NULL, 0) +#define libssh2_md5_update(ctx, data, datalen) \ + mbedtls_md_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_md5_final(ctx, hash) \ + _libssh2_mbedtls_hash_final(&ctx, hash) +#define libssh2_md5(data, datalen, hash) \ + _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_MD5, hash) + +/*******************************************************************/ +/* + * mbedTLS backend: RSA structure + */ + +#define libssh2_rsa_ctx mbedtls_rsa_context + +#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \ + d, d_len, p, p_len, q, q_len, \ + e1, e1_len, e2, e2_len, c, c_len) \ + _libssh2_mbedtls_rsa_new(rsactx, e, e_len, n, n_len, \ + d, d_len, p, p_len, q, q_len, \ + e1, e1_len, e2, e2_len, c, c_len) + +#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \ + _libssh2_mbedtls_rsa_new_private(rsactx, s, filename, passphrase) + +#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \ + filedata_len, passphrase) \ + _libssh2_mbedtls_rsa_new_private_frommemory(rsactx, s, filedata, \ + filedata_len, passphrase) + +#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \ + _libssh2_mbedtls_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) + +#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \ + _libssh2_mbedtls_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) + +#define _libssh2_rsa_free(rsactx) \ + _libssh2_mbedtls_rsa_free(rsactx) + +/* + * mbedTLS backend: Key functions + */ + +#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \ + _libssh2_mbedtls_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) +#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ + pk, pk_len, pw) \ + _libssh2_mbedtls_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ + pk, pk_len, pw) + + + /*******************************************************************/ +/* + * mbedTLS backend: Cipher Context structure + */ +#define _libssh2_cipher_ctx mbedtls_cipher_context_t + +#define _libssh2_cipher_type(algo) mbedtls_cipher_type_t algo + +#define _libssh2_cipher_aes256ctr MBEDTLS_CIPHER_AES_256_CTR +#define _libssh2_cipher_aes192ctr MBEDTLS_CIPHER_AES_192_CTR +#define _libssh2_cipher_aes128ctr MBEDTLS_CIPHER_AES_128_CTR +#define _libssh2_cipher_aes256 MBEDTLS_CIPHER_AES_256_CBC +#define _libssh2_cipher_aes192 MBEDTLS_CIPHER_AES_192_CBC +#define _libssh2_cipher_aes128 MBEDTLS_CIPHER_AES_128_CBC +#define _libssh2_cipher_blowfish MBEDTLS_CIPHER_BLOWFISH_CBC +#define _libssh2_cipher_arcfour MBEDTLS_CIPHER_ARC4_128 +#define _libssh2_cipher_cast5 MBEDTLS_CIPHER_NULL +#define _libssh2_cipher_3des MBEDTLS_CIPHER_DES_EDE3_CBC + +/* + * mbedTLS backend: Cipher functions + */ + +#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \ + _libssh2_mbedtls_cipher_init(ctx, type, iv, secret, encrypt) +#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen) \ + _libssh2_mbedtls_cipher_crypt(ctx, type, encrypt, block, blocklen) +#define _libssh2_cipher_dtor(ctx) \ + _libssh2_mbedtls_cipher_dtor(ctx) + + +/*******************************************************************/ +/* + * mbedTLS backend: BigNumber Support + */ + +#define _libssh2_bn_ctx int /* not used */ +#define _libssh2_bn_ctx_new() 0 /* not used */ +#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */ + +#define _libssh2_bn mbedtls_mpi + +#define _libssh2_bn_init() \ + _libssh2_mbedtls_bignum_init() +#define _libssh2_bn_init_from_bin() \ + _libssh2_mbedtls_bignum_init() +#define _libssh2_bn_rand(bn, bits, top, bottom) \ + _libssh2_mbedtls_bignum_random(bn, bits, top, bottom) +#define _libssh2_bn_mod_exp(r, a, p, m, ctx) \ + mbedtls_mpi_exp_mod(r, a, p, m, NULL) +#define _libssh2_bn_set_word(bn, word) \ + mbedtls_mpi_lset(bn, word) +#define _libssh2_bn_from_bin(bn, len, bin) \ + mbedtls_mpi_read_binary(bn, bin, len) +#define _libssh2_bn_to_bin(bn, bin) \ + mbedtls_mpi_write_binary(bn, bin, mbedtls_mpi_size(bn)) +#define _libssh2_bn_bytes(bn) \ + mbedtls_mpi_size(bn) +#define _libssh2_bn_bits(bn) \ + mbedtls_mpi_bitlen(bn) +#define _libssh2_bn_free(bn) \ + mbedtls_mpi_free(bn) + + +/*******************************************************************/ +/* + * mbedTLS backend: forward declarations + */ +void +_libssh2_mbedtls_init(void); + +void +_libssh2_mbedtls_free(void); + +int +_libssh2_mbedtls_random(unsigned char *buf, int len); + +int +_libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + unsigned char *iv, + unsigned char *secret, + int encrypt); +int +_libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + int encrypt, + unsigned char *block, + size_t blocklen); +void +_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx); + +int +_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, + mbedtls_md_type_t mdtype, + const unsigned char *key, unsigned long keylen); + +int +_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash); +int +_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, + mbedtls_md_type_t mdtype, unsigned char *hash); + +_libssh2_bn * +_libssh2_mbedtls_bignum_init(void); + +void +_libssh2_mbedtls_bignum_free(_libssh2_bn *bn); + +int +_libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom); + +int +_libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen); + +int +_libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase); + +int +_libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); +int +_libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len); +int +_libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len); +void +_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *rsa); + +int +_libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase); +int +_libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase); diff --git a/libssh2/src/misc.c b/libssh2/src/misc.c new file mode 100644 index 000000000..f7faae7b6 --- /dev/null +++ b/libssh2/src/misc.c @@ -0,0 +1,645 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2009-2014 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#include +#include + +int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char* errmsg, int errflags) +{ + if (session->err_flags & LIBSSH2_ERR_FLAG_DUP) + LIBSSH2_FREE(session, (char *)session->err_msg); + + session->err_code = errcode; + session->err_flags = 0; + + if ((errmsg != NULL) && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) { + size_t len = strlen(errmsg); + char *copy = LIBSSH2_ALLOC(session, len + 1); + if (copy) { + memcpy(copy, errmsg, len + 1); + session->err_flags = LIBSSH2_ERR_FLAG_DUP; + session->err_msg = copy; + } + else + /* Out of memory: this code path is very unlikely */ + session->err_msg = "former error forgotten (OOM)"; + } + else + session->err_msg = errmsg; + +#ifdef LIBSSH2DEBUG + if((errcode == LIBSSH2_ERROR_EAGAIN) && !session->api_block_mode) + /* if this is EAGAIN and we're in non-blocking mode, don't generate + a debug output for this */ + return errcode; + _libssh2_debug(session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code, + session->err_msg); +#endif + + return errcode; +} + +int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg) +{ + return _libssh2_error_flags(session, errcode, errmsg, 0); +} + +#ifdef WIN32 +static int wsa2errno(void) +{ + switch (WSAGetLastError()) { + case WSAEWOULDBLOCK: + return EAGAIN; + + case WSAENOTSOCK: + return EBADF; + + case WSAEINTR: + return EINTR; + + default: + /* It is most important to ensure errno does not stay at EAGAIN + * when a different error occurs so just set errno to a generic + * error */ + return EIO; + } +} +#endif + +/* _libssh2_recv + * + * Replacement for the standard recv, return -errno on failure. + */ +ssize_t +_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, + int flags, void **abstract) +{ + ssize_t rc; + + (void) abstract; + + rc = recv(sock, buffer, length, flags); +#ifdef WIN32 + if (rc < 0 ) + return -wsa2errno(); +#elif defined(__VMS) + if (rc < 0 ){ + if ( errno == EWOULDBLOCK ) + return -EAGAIN; + else + return -errno; + } +#else + if (rc < 0 ){ + /* Sometimes the first recv() function call sets errno to ENOENT on + Solaris and HP-UX */ + if ( errno == ENOENT ) + return -EAGAIN; + else + return -errno; + } +#endif + return rc; +} + +/* _libssh2_send + * + * Replacement for the standard send, return -errno on failure. + */ +ssize_t +_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length, + int flags, void **abstract) +{ + ssize_t rc; + + (void) abstract; + + rc = send(sock, buffer, length, flags); +#ifdef WIN32 + if (rc < 0 ) + return -wsa2errno(); +#elif defined(__VMS) + if (rc < 0 ) { + if ( errno == EWOULDBLOCK ) + return -EAGAIN; + else + return -errno; + } +#else + if (rc < 0 ) + return -errno; +#endif + return rc; +} + +/* libssh2_ntohu32 + */ +unsigned int +_libssh2_ntohu32(const unsigned char *buf) +{ + return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; +} + + +/* _libssh2_ntohu64 + */ +libssh2_uint64_t +_libssh2_ntohu64(const unsigned char *buf) +{ + unsigned long msl, lsl; + + msl = ((libssh2_uint64_t)buf[0] << 24) | ((libssh2_uint64_t)buf[1] << 16) + | ((libssh2_uint64_t)buf[2] << 8) | (libssh2_uint64_t)buf[3]; + lsl = ((libssh2_uint64_t)buf[4] << 24) | ((libssh2_uint64_t)buf[5] << 16) + | ((libssh2_uint64_t)buf[6] << 8) | (libssh2_uint64_t)buf[7]; + + return ((libssh2_uint64_t)msl <<32) | lsl; +} + +/* _libssh2_htonu32 + */ +void +_libssh2_htonu32(unsigned char *buf, uint32_t value) +{ + buf[0] = (value >> 24) & 0xFF; + buf[1] = (value >> 16) & 0xFF; + buf[2] = (value >> 8) & 0xFF; + buf[3] = value & 0xFF; +} + +/* _libssh2_store_u32 + */ +void _libssh2_store_u32(unsigned char **buf, uint32_t value) +{ + _libssh2_htonu32(*buf, value); + *buf += sizeof(uint32_t); +} + +/* _libssh2_store_str + */ +void _libssh2_store_str(unsigned char **buf, const char *str, size_t len) +{ + _libssh2_store_u32(buf, (uint32_t)len); + if(len) { + memcpy(*buf, str, len); + *buf += len; + } +} + +/* Base64 Conversion */ + +static const short base64_reverse_table[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* libssh2_base64_decode + * + * Decode a base64 chunk and store it into a newly alloc'd buffer + */ +LIBSSH2_API int +libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, + unsigned int *datalen, const char *src, + unsigned int src_len) +{ + unsigned char *s, *d; + short v; + int i = 0, len = 0; + + *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); + d = (unsigned char *) *data; + if (!d) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for base64 decoding"); + } + + for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) { + if ((v = base64_reverse_table[*s]) < 0) + continue; + switch (i % 4) { + case 0: + d[len] = (unsigned char)(v << 2); + break; + case 1: + d[len++] |= v >> 4; + d[len] = (unsigned char)(v << 4); + break; + case 2: + d[len++] |= v >> 2; + d[len] = (unsigned char)(v << 6); + break; + case 3: + d[len++] |= v; + break; + } + i++; + } + if ((i % 4) == 1) { + /* Invalid -- We have a byte which belongs exclusively to a partial + octet */ + LIBSSH2_FREE(session, *data); + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64"); + } + + *datalen = len; + return 0; +} + +/* ---- Base64 Encoding/Decoding Table --- */ +static const char table64[]= + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* + * _libssh2_base64_encode() + * + * Returns the length of the newly created base64 string. The third argument + * is a pointer to an allocated area holding the base64 data. If something + * went wrong, 0 is returned. + * + */ +size_t _libssh2_base64_encode(LIBSSH2_SESSION *session, + const char *inp, size_t insize, char **outptr) +{ + unsigned char ibuf[3]; + unsigned char obuf[4]; + int i; + int inputparts; + char *output; + char *base64data; + const char *indata = inp; + + *outptr = NULL; /* set to NULL in case of failure before we reach the end */ + + if(0 == insize) + insize = strlen(indata); + + base64data = output = LIBSSH2_ALLOC(session, insize*4/3+4); + if(NULL == output) + return 0; + + while(insize > 0) { + for (i = inputparts = 0; i < 3; i++) { + if(insize > 0) { + inputparts++; + ibuf[i] = *indata; + indata++; + insize--; + } + else + ibuf[i] = 0; + } + + obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2); + obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \ + ((ibuf[1] & 0xF0) >> 4)); + obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \ + ((ibuf[2] & 0xC0) >> 6)); + obuf[3] = (unsigned char) (ibuf[2] & 0x3F); + + switch(inputparts) { + case 1: /* only one byte read */ + snprintf(output, 5, "%c%c==", + table64[obuf[0]], + table64[obuf[1]]); + break; + case 2: /* two bytes read */ + snprintf(output, 5, "%c%c%c=", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]]); + break; + default: + snprintf(output, 5, "%c%c%c%c", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]], + table64[obuf[3]] ); + break; + } + output += 4; + } + *output=0; + *outptr = base64data; /* make it return the actual data memory */ + + return strlen(base64data); /* return the length of the new data */ +} +/* ---- End of Base64 Encoding ---- */ + +LIBSSH2_API void +libssh2_free(LIBSSH2_SESSION *session, void *ptr) +{ + LIBSSH2_FREE(session, ptr); +} + +#ifdef LIBSSH2DEBUG +#include + +LIBSSH2_API int +libssh2_trace(LIBSSH2_SESSION * session, int bitmask) +{ + session->showmask = bitmask; + return 0; +} + +LIBSSH2_API int +libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, + libssh2_trace_handler_func callback) +{ + session->tracehandler = callback; + session->tracehandler_context = handler_context; + return 0; +} + +void +_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...) +{ + char buffer[1536]; + int len, msglen, buflen = sizeof(buffer); + va_list vargs; + struct timeval now; + static int firstsec; + static const char *const contexts[] = { + "Unknown", + "Transport", + "Key Ex", + "Userauth", + "Conn", + "SCP", + "SFTP", + "Failure Event", + "Publickey", + "Socket", + }; + const char* contexttext = contexts[0]; + unsigned int contextindex; + + if (!(session->showmask & context)) { + /* no such output asked for */ + return; + } + + /* Find the first matching context string for this message */ + for (contextindex = 0; contextindex < ARRAY_SIZE(contexts); + contextindex++) { + if ((context & (1 << contextindex)) != 0) { + contexttext = contexts[contextindex]; + break; + } + } + + _libssh2_gettimeofday(&now, NULL); + if(!firstsec) { + firstsec = now.tv_sec; + } + now.tv_sec -= firstsec; + + len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ", + (int)now.tv_sec, (int)now.tv_usec, contexttext); + + if (len >= buflen) + msglen = buflen - 1; + else { + buflen -= len; + msglen = len; + va_start(vargs, format); + len = vsnprintf(buffer + msglen, buflen, format, vargs); + va_end(vargs); + msglen += len < buflen ? len : buflen - 1; + } + + if (session->tracehandler) + (session->tracehandler)(session, session->tracehandler_context, buffer, + msglen); + else + fprintf(stderr, "%s\n", buffer); +} + +#else +LIBSSH2_API int +libssh2_trace(LIBSSH2_SESSION * session, int bitmask) +{ + (void) session; + (void) bitmask; + return 0; +} + +LIBSSH2_API int +libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, + libssh2_trace_handler_func callback) +{ + (void) session; + (void) handler_context; + (void) callback; + return 0; +} +#endif + +/* init the list head */ +void _libssh2_list_init(struct list_head *head) +{ + head->first = head->last = NULL; +} + +/* add a node to the list */ +void _libssh2_list_add(struct list_head *head, + struct list_node *entry) +{ + /* store a pointer to the head */ + entry->head = head; + + /* we add this entry at the "top" so it has no next */ + entry->next = NULL; + + /* make our prev point to what the head thinks is last */ + entry->prev = head->last; + + /* and make head's last be us now */ + head->last = entry; + + /* make sure our 'prev' node points to us next */ + if(entry->prev) + entry->prev->next = entry; + else + head->first = entry; +} + +/* return the "first" node in the list this head points to */ +void *_libssh2_list_first(struct list_head *head) +{ + return head->first; +} + +/* return the next node in the list */ +void *_libssh2_list_next(struct list_node *node) +{ + return node->next; +} + +/* return the prev node in the list */ +void *_libssh2_list_prev(struct list_node *node) +{ + return node->prev; +} + +/* remove this node from the list */ +void _libssh2_list_remove(struct list_node *entry) +{ + if(entry->prev) + entry->prev->next = entry->next; + else + entry->head->first = entry->next; + + if(entry->next) + entry->next->prev = entry->prev; + else + entry->head->last = entry->prev; +} + +#if 0 +/* insert a node before the given 'after' entry */ +void _libssh2_list_insert(struct list_node *after, /* insert before this */ + struct list_node *entry) +{ + /* 'after' is next to 'entry' */ + bentry->next = after; + + /* entry's prev is then made to be the prev after current has */ + entry->prev = after->prev; + + /* the node that is now before 'entry' was previously before 'after' + and must be made to point to 'entry' correctly */ + if(entry->prev) + entry->prev->next = entry; + else + /* there was no node before this, so we make sure we point the head + pointer to this node */ + after->head->first = entry; + + /* after's prev entry points back to entry */ + after->prev = entry; + + /* after's next entry is still the same as before */ + + /* entry's head is the same as after's */ + entry->head = after->head; +} + +#endif + +/* this define is defined in misc.h for the correct platforms */ +#ifdef LIBSSH2_GETTIMEOFDAY_WIN32 +/* + * gettimeofday + * Implementation according to: + * The Open Group Base Specifications Issue 6 + * IEEE Std 1003.1, 2004 Edition + */ + +/* + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Contributed by: + * Danny Smith + */ + +/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ +#define _W32_FT_OFFSET (116444736000000000) + +int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp) + { + union { + unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */ + FILETIME ft; + } _now; + (void)tzp; + if(tp) + { + GetSystemTimeAsFileTime (&_now.ft); + tp->tv_usec=(long)((_now.ns100 / 10) % 1000000 ); + tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000); + } + /* Always return 0 as per Open Group Base Specifications Issue 6. + Do not set errno on error. */ + return 0; +} + + +#endif + +void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size) +{ + void *p = LIBSSH2_ALLOC(session, size); + if(p) { + memset(p, 0, size); + } + return p; +} diff --git a/libssh2/src/misc.h b/libssh2/src/misc.h new file mode 100644 index 000000000..54ae5461d --- /dev/null +++ b/libssh2/src/misc.h @@ -0,0 +1,96 @@ +#ifndef __LIBSSH2_MISC_H +#define __LIBSSH2_MISC_H +/* Copyright (c) 2009-2014 by Daniel Stenberg + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +struct list_head { + struct list_node *last; + struct list_node *first; +}; + +struct list_node { + struct list_node *next; + struct list_node *prev; + struct list_head *head; +}; + +int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char* errmsg, int errflags); +int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg); + +void _libssh2_list_init(struct list_head *head); + +/* add a node last in the list */ +void _libssh2_list_add(struct list_head *head, + struct list_node *entry); + +/* return the "first" node in the list this head points to */ +void *_libssh2_list_first(struct list_head *head); + +/* return the next node in the list */ +void *_libssh2_list_next(struct list_node *node); + +/* return the prev node in the list */ +void *_libssh2_list_prev(struct list_node *node); + +/* remove this node from the list */ +void _libssh2_list_remove(struct list_node *entry); + +size_t _libssh2_base64_encode(struct _LIBSSH2_SESSION *session, + const char *inp, size_t insize, char **outptr); + +unsigned int _libssh2_ntohu32(const unsigned char *buf); +libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf); +void _libssh2_htonu32(unsigned char *buf, uint32_t val); +void _libssh2_store_u32(unsigned char **buf, uint32_t value); +void _libssh2_store_str(unsigned char **buf, const char *str, size_t len); +void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size); + +#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) +/* provide a private one */ +#undef HAVE_GETTIMEOFDAY +int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp); +#define HAVE_LIBSSH2_GETTIMEOFDAY +#define LIBSSH2_GETTIMEOFDAY_WIN32 /* enable the win32 implementation */ +#else +#ifdef HAVE_GETTIMEOFDAY +#define _libssh2_gettimeofday(x,y) gettimeofday(x,y) +#define HAVE_LIBSSH2_GETTIMEOFDAY +#endif +#endif + +#endif /* _LIBSSH2_MISC_H */ diff --git a/libssh2/src/openssl.c b/libssh2/src/openssl.c new file mode 100644 index 000000000..4f63ef92b --- /dev/null +++ b/libssh2/src/openssl.c @@ -0,0 +1,1192 @@ +/* Copyright (C) 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. + * Copyright (c) 2004-2006, Sara Golemon + * + * Author: Simon Josefsson + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_OPENSSL /* compile only if we build with openssl */ + +#include + +#ifndef EVP_MAX_BLOCK_LENGTH +#define EVP_MAX_BLOCK_LENGTH 32 +#endif + +int +_libssh2_rsa_new(libssh2_rsa_ctx ** rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen) +{ + BIGNUM * e; + BIGNUM * n; + BIGNUM * d = 0; + BIGNUM * p = 0; + BIGNUM * q = 0; + BIGNUM * dmp1 = 0; + BIGNUM * dmq1 = 0; + BIGNUM * iqmp = 0; + + e = BN_new(); + BN_bin2bn(edata, elen, e); + + n = BN_new(); + BN_bin2bn(ndata, nlen, n); + + if (ddata) { + d = BN_new(); + BN_bin2bn(ddata, dlen, d); + + p = BN_new(); + BN_bin2bn(pdata, plen, p); + + q = BN_new(); + BN_bin2bn(qdata, qlen, q); + + dmp1 = BN_new(); + BN_bin2bn(e1data, e1len, dmp1); + + dmq1 = BN_new(); + BN_bin2bn(e2data, e2len, dmq1); + + iqmp = BN_new(); + BN_bin2bn(coeffdata, coefflen, iqmp); + } + + *rsa = RSA_new(); +#ifdef HAVE_OPAQUE_STRUCTS + RSA_set0_key(*rsa, n, e, d); +#else + (*rsa)->e = e; + (*rsa)->n = n; +#endif + +#ifdef HAVE_OPAQUE_STRUCTS + RSA_set0_factors(*rsa, p, q); +#else + (*rsa)->p = p; + (*rsa)->q = q; +#endif + +#ifdef HAVE_OPAQUE_STRUCTS + RSA_set0_crt_params(*rsa, dmp1, dmq1, iqmp); +#else + (*rsa)->dmp1 = dmp1; + (*rsa)->dmq1 = dmq1; + (*rsa)->iqmp = iqmp; +#endif + return 0; +} + +int +_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + int ret; + + if (_libssh2_sha1(m, m_len, hash)) + return -1; /* failure */ + ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH, + (unsigned char *) sig, sig_len, rsactx); + return (ret == 1) ? 0 : -1; +} + +#if LIBSSH2_DSA +int +_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx, + const unsigned char *p, + unsigned long p_len, + const unsigned char *q, + unsigned long q_len, + const unsigned char *g, + unsigned long g_len, + const unsigned char *y, + unsigned long y_len, + const unsigned char *x, unsigned long x_len) +{ + BIGNUM * p_bn; + BIGNUM * q_bn; + BIGNUM * g_bn; + BIGNUM * pub_key; + BIGNUM * priv_key = NULL; + + p_bn = BN_new(); + BN_bin2bn(p, p_len, p_bn); + + q_bn = BN_new(); + BN_bin2bn(q, q_len, q_bn); + + g_bn = BN_new(); + BN_bin2bn(g, g_len, g_bn); + + pub_key = BN_new(); + BN_bin2bn(y, y_len, pub_key); + + if (x_len) { + priv_key = BN_new(); + BN_bin2bn(x, x_len, priv_key); + } + + *dsactx = DSA_new(); + +#ifdef HAVE_OPAQUE_STRUCTS + DSA_set0_pqg(*dsactx, p_bn, q_bn, g_bn); +#else + (*dsactx)->p = p_bn; + (*dsactx)->g = g_bn; + (*dsactx)->q = q_bn; +#endif + +#ifdef HAVE_OPAQUE_STRUCTS + DSA_set0_key(*dsactx, pub_key, priv_key); +#else + (*dsactx)->pub_key = pub_key; + (*dsactx)->priv_key = priv_key; +#endif + return 0; +} + +int +_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + DSA_SIG * dsasig; + BIGNUM * r; + BIGNUM * s; + int ret = -1; + + r = BN_new(); + BN_bin2bn(sig, 20, r); + s = BN_new(); + BN_bin2bn(sig + 20, 20, s); + + dsasig = DSA_SIG_new(); +#ifdef HAVE_OPAQUE_STRUCTS + DSA_SIG_set0(dsasig, r, s); +#else + dsasig->r = r; + dsasig->s = s; +#endif + if (!_libssh2_sha1(m, m_len, hash)) + /* _libssh2_sha1() succeeded */ + ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, dsasig, dsactx); + + DSA_SIG_free(dsasig); + + return (ret == 1) ? 0 : -1; +} +#endif /* LIBSSH_DSA */ + +int +_libssh2_cipher_init(_libssh2_cipher_ctx * h, + _libssh2_cipher_type(algo), + unsigned char *iv, unsigned char *secret, int encrypt) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *h = EVP_CIPHER_CTX_new(); + return !EVP_CipherInit(*h, algo(), secret, iv, encrypt); +#else + EVP_CIPHER_CTX_init(h); + return !EVP_CipherInit(h, algo(), secret, iv, encrypt); +#endif +} + +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blocksize) +{ + unsigned char buf[EVP_MAX_BLOCK_LENGTH]; + int ret; + (void) algo; + (void) encrypt; + +#ifdef HAVE_OPAQUE_STRUCTS + ret = EVP_Cipher(*ctx, buf, block, blocksize); +#else + ret = EVP_Cipher(ctx, buf, block, blocksize); +#endif + if (ret == 1) { + memcpy(block, buf, blocksize); + } + return ret == 1 ? 0 : 1; +} + +#if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) + +#include +#include + +typedef struct +{ + AES_KEY key; + EVP_CIPHER_CTX *aes_ctx; + unsigned char ctr[AES_BLOCK_SIZE]; +} aes_ctr_ctx; + +static int +aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) /* init key */ +{ + /* + * variable "c" is leaked from this scope, but is later freed + * in aes_ctr_cleanup + */ + aes_ctr_ctx *c; + const EVP_CIPHER *aes_cipher; + (void) enc; + + switch (EVP_CIPHER_CTX_key_length(ctx)) { + case 16: + aes_cipher = EVP_aes_128_ecb(); + break; + case 24: + aes_cipher = EVP_aes_192_ecb(); + break; + case 32: + aes_cipher = EVP_aes_256_ecb(); + break; + default: + return 0; + } + + c = malloc(sizeof(*c)); + if (c == NULL) + return 0; + +#ifdef HAVE_OPAQUE_STRUCTS + c->aes_ctx = EVP_CIPHER_CTX_new(); +#else + c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX)); +#endif + if (c->aes_ctx == NULL) { + free(c); + return 0; + } + + if (EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) { +#ifdef HAVE_OPAQUE_STRUCTS + EVP_CIPHER_CTX_free(c->aes_ctx); +#else + free(c->aes_ctx); +#endif + free(c); + return 0; + } + + EVP_CIPHER_CTX_set_padding(c->aes_ctx, 0); + + memcpy(c->ctr, iv, AES_BLOCK_SIZE); + + EVP_CIPHER_CTX_set_app_data(ctx, c); + + return 1; +} + +static int +aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, + size_t inl) /* encrypt/decrypt data */ +{ + aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx); + unsigned char b1[AES_BLOCK_SIZE]; + size_t i = 0; + int outlen = 0; + + if (inl != 16) /* libssh2 only ever encrypt one block */ + return 0; + + if (c == NULL) { + return 0; + } + +/* + To encrypt a packet P=P1||P2||...||Pn (where P1, P2, ..., Pn are each + blocks of length L), the encryptor first encrypts with + to obtain a block B1. The block B1 is then XORed with P1 to generate + the ciphertext block C1. The counter X is then incremented +*/ + + if (EVP_EncryptUpdate(c->aes_ctx, b1, &outlen, c->ctr, AES_BLOCK_SIZE) != 1) { + return 0; + } + + for (i = 0; i < 16; i++) + *out++ = *in++ ^ b1[i]; + + i = 15; + while (c->ctr[i]++ == 0xFF) { + if (i == 0) + break; + i--; + } + + return 1; +} + +static int +aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */ +{ + aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx); + + if (c == NULL) { + return 1; + } + + if (c->aes_ctx != NULL) { +#ifdef HAVE_OPAQUE_STRUCTS + EVP_CIPHER_CTX_free(c->aes_ctx); +#else + _libssh2_cipher_dtor(c->aes_ctx); + free(c->aes_ctx); +#endif + } + + free(c); + + return 1; +} + +static const EVP_CIPHER * +make_ctr_evp (size_t keylen, EVP_CIPHER *aes_ctr_cipher, int type) +{ +#ifdef HAVE_OPAQUE_STRUCTS + aes_ctr_cipher = EVP_CIPHER_meth_new(type, 16, keylen); + if (aes_ctr_cipher) { + EVP_CIPHER_meth_set_iv_length(aes_ctr_cipher, 16); + EVP_CIPHER_meth_set_init(aes_ctr_cipher, aes_ctr_init); + EVP_CIPHER_meth_set_do_cipher(aes_ctr_cipher, aes_ctr_do_cipher); + EVP_CIPHER_meth_set_cleanup(aes_ctr_cipher, aes_ctr_cleanup); + } +#else + aes_ctr_cipher->nid = type; + aes_ctr_cipher->block_size = 16; + aes_ctr_cipher->key_len = keylen; + aes_ctr_cipher->iv_len = 16; + aes_ctr_cipher->init = aes_ctr_init; + aes_ctr_cipher->do_cipher = aes_ctr_do_cipher; + aes_ctr_cipher->cleanup = aes_ctr_cleanup; +#endif + + return aes_ctr_cipher; +} + +const EVP_CIPHER * +_libssh2_EVP_aes_128_ctr(void) +{ +#ifdef HAVE_OPAQUE_STRUCTS + static EVP_CIPHER * aes_ctr_cipher; + return !aes_ctr_cipher? + make_ctr_evp (16, aes_ctr_cipher, NID_aes_128_ctr) : aes_ctr_cipher; +#else + static EVP_CIPHER aes_ctr_cipher; + return !aes_ctr_cipher.key_len? + make_ctr_evp (16, &aes_ctr_cipher, 0) : &aes_ctr_cipher; +#endif +} + +const EVP_CIPHER * +_libssh2_EVP_aes_192_ctr(void) +{ +#ifdef HAVE_OPAQUE_STRUCTS + static EVP_CIPHER * aes_ctr_cipher; + return !aes_ctr_cipher? + make_ctr_evp (24, aes_ctr_cipher, NID_aes_192_ctr) : aes_ctr_cipher; +#else + static EVP_CIPHER aes_ctr_cipher; + return !aes_ctr_cipher.key_len? + make_ctr_evp (24, &aes_ctr_cipher, 0) : &aes_ctr_cipher; +#endif +} + +const EVP_CIPHER * +_libssh2_EVP_aes_256_ctr(void) +{ +#ifdef HAVE_OPAQUE_STRUCTS + static EVP_CIPHER * aes_ctr_cipher; + return !aes_ctr_cipher? + make_ctr_evp (32, aes_ctr_cipher, NID_aes_256_ctr) : aes_ctr_cipher; +#else + static EVP_CIPHER aes_ctr_cipher; + return !aes_ctr_cipher.key_len? + make_ctr_evp (32, &aes_ctr_cipher, 0) : &aes_ctr_cipher; +#endif +} + +void _libssh2_init_aes_ctr(void) +{ + _libssh2_EVP_aes_128_ctr(); + _libssh2_EVP_aes_192_ctr(); + _libssh2_EVP_aes_256_ctr(); +} + +#else +void _libssh2_init_aes_ctr(void) {} +#endif /* LIBSSH2_AES_CTR */ + +/* TODO: Optionally call a passphrase callback specified by the + * calling program + */ +static int +passphrase_cb(char *buf, int size, int rwflag, char *passphrase) +{ + int passphrase_len = strlen(passphrase); + (void) rwflag; + + if (passphrase_len > (size - 1)) { + passphrase_len = size - 1; + } + memcpy(buf, passphrase, passphrase_len); + buf[passphrase_len] = '\0'; + + return passphrase_len; +} + +typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *, + void * u); + +static int +read_private_key_from_memory(void ** key_ctx, + pem_read_bio_func read_private_key, + const char * filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ + BIO * bp; + + *key_ctx = NULL; + + bp = BIO_new_mem_buf((char *)filedata, filedata_len); + if (!bp) { + return -1; + } + *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb, + (void *) passphrase); + + BIO_free(bp); + return (*key_ctx) ? 0 : -1; +} + +static int +read_private_key_from_file(void ** key_ctx, + pem_read_bio_func read_private_key, + const char * filename, + unsigned const char *passphrase) +{ + BIO * bp; + + *key_ctx = NULL; + + bp = BIO_new_file(filename, "r"); + if (!bp) { + return -1; + } + + *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb, + (void *) passphrase); + + BIO_free(bp); + return (*key_ctx) ? 0 : -1; +} + +int +_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + pem_read_bio_func read_rsa = + (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey; + (void) session; + + _libssh2_init_if_needed(); + + return read_private_key_from_memory((void **) rsa, read_rsa, + filedata, filedata_len, passphrase); +} + +int +_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + pem_read_bio_func read_rsa = + (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey; + (void) session; + + _libssh2_init_if_needed (); + + return read_private_key_from_file((void **) rsa, read_rsa, + filename, passphrase); +} + +#if LIBSSH2_DSA +int +_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + pem_read_bio_func read_dsa = + (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey; + (void) session; + + _libssh2_init_if_needed(); + + return read_private_key_from_memory((void **) dsa, read_dsa, + filedata, filedata_len, passphrase); +} + +int +_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + pem_read_bio_func read_dsa = + (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey; + (void) session; + + _libssh2_init_if_needed (); + + return read_private_key_from_file((void **) dsa, read_dsa, + filename, passphrase); +} +#endif /* LIBSSH_DSA */ + +int +_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, size_t *signature_len) +{ + int ret; + unsigned char *sig; + unsigned int sig_len; + + sig_len = RSA_size(rsactx); + sig = LIBSSH2_ALLOC(session, sig_len); + + if (!sig) { + return -1; + } + + ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx); + + if (!ret) { + LIBSSH2_FREE(session, sig); + return -1; + } + + *signature = sig; + *signature_len = sig_len; + + return 0; +} + +#if LIBSSH2_DSA +int +_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *signature) +{ + DSA_SIG *sig; + const BIGNUM * r; + const BIGNUM * s; + int r_len, s_len; + (void) hash_len; + + sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); + if (!sig) { + return -1; + } + +#ifdef HAVE_OPAQUE_STRUCTS + DSA_SIG_get0(sig, &r, &s); +#else + r = sig->r; + s = sig->s; +#endif + r_len = BN_num_bytes(r); + if (r_len < 1 || r_len > 20) { + DSA_SIG_free(sig); + return -1; + } + s_len = BN_num_bytes(s); + if (s_len < 1 || s_len > 20) { + DSA_SIG_free(sig); + return -1; + } + + memset(signature, 0, 40); + + BN_bn2bin(r, signature + (20 - r_len)); + BN_bn2bin(s, signature + 20 + (20 - s_len)); + + DSA_SIG_free(sig); + + return 0; +} +#endif /* LIBSSH_DSA */ + +int +_libssh2_sha1_init(libssh2_sha1_ctx *ctx) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *ctx = EVP_MD_CTX_new(); + + if (*ctx == NULL) + return 0; + + if (EVP_DigestInit(*ctx, EVP_get_digestbyname("sha1"))) + return 1; + + EVP_MD_CTX_free(*ctx); + *ctx = NULL; + + return 0; +#else + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("sha1")); +#endif +} + +int +_libssh2_sha1(const unsigned char *message, unsigned long len, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + EVP_MD_CTX * ctx = EVP_MD_CTX_new(); + + if (ctx == NULL) + return 1; /* error */ + + if (EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"))) { + EVP_DigestUpdate(ctx, message, len); + EVP_DigestFinal(ctx, out, NULL); + EVP_MD_CTX_free(ctx); + return 0; /* success */ + } + EVP_MD_CTX_free(ctx); +#else + EVP_MD_CTX ctx; + + EVP_MD_CTX_init(&ctx); + if (EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"))) { + EVP_DigestUpdate(&ctx, message, len); + EVP_DigestFinal(&ctx, out, NULL); + return 0; /* success */ + } +#endif + return 1; /* error */ +} + +int +_libssh2_sha256_init(libssh2_sha256_ctx *ctx) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *ctx = EVP_MD_CTX_new(); + + if (*ctx == NULL) + return 0; + + if (EVP_DigestInit(*ctx, EVP_get_digestbyname("sha256"))) + return 1; + + EVP_MD_CTX_free(*ctx); + *ctx = NULL; + + return 0; +#else + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("sha256")); +#endif +} + +int +_libssh2_sha256(const unsigned char *message, unsigned long len, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + EVP_MD_CTX * ctx = EVP_MD_CTX_new(); + + if (ctx == NULL) + return 1; /* error */ + + if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha256"))) { + EVP_DigestUpdate(ctx, message, len); + EVP_DigestFinal(ctx, out, NULL); + EVP_MD_CTX_free(ctx); + return 0; /* success */ + } + EVP_MD_CTX_free(ctx); +#else + EVP_MD_CTX ctx; + + EVP_MD_CTX_init(&ctx); + if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha256"))) { + EVP_DigestUpdate(&ctx, message, len); + EVP_DigestFinal(&ctx, out, NULL); + return 0; /* success */ + } +#endif + return 1; /* error */ +} + +int +_libssh2_md5_init(libssh2_md5_ctx *ctx) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *ctx = EVP_MD_CTX_new(); + + if (*ctx == NULL) + return 0; + + if (EVP_DigestInit(*ctx, EVP_get_digestbyname("md5"))) + return 1; + + EVP_MD_CTX_free(*ctx); + *ctx = NULL; + + return 0; +#else + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("md5")); +#endif +} + +static unsigned char * +write_bn(unsigned char *buf, const BIGNUM *bn, int bn_bytes) +{ + unsigned char *p = buf; + + /* Left space for bn size which will be written below. */ + p += 4; + + *p = 0; + BN_bn2bin(bn, p + 1); + if (!(*(p + 1) & 0x80)) { + memmove(p, p + 1, --bn_bytes); + } + _libssh2_htonu32(p - 4, bn_bytes); /* Post write bn size. */ + + return p + bn_bytes; +} + +static unsigned char * +gen_publickey_from_rsa(LIBSSH2_SESSION *session, RSA *rsa, + size_t *key_len) +{ + int e_bytes, n_bytes; + unsigned long len; + unsigned char* key; + unsigned char* p; + const BIGNUM * e; + const BIGNUM * n; +#ifdef HAVE_OPAQUE_STRUCTS + RSA_get0_key(rsa, &n, &e, NULL); +#else + e = rsa->e; + n = rsa->n; +#endif + e_bytes = BN_num_bytes(e) + 1; + n_bytes = BN_num_bytes(n) + 1; + + /* Key form is "ssh-rsa" + e + n. */ + len = 4 + 7 + 4 + e_bytes + 4 + n_bytes; + + key = LIBSSH2_ALLOC(session, len); + if (key == NULL) { + return NULL; + } + + /* Process key encoding. */ + p = key; + + _libssh2_htonu32(p, 7); /* Key type. */ + p += 4; + memcpy(p, "ssh-rsa", 7); + p += 7; + + p = write_bn(p, e, e_bytes); + p = write_bn(p, n, n_bytes); + + *key_len = (size_t)(p - key); + return key; +} + +#if LIBSSH2_DSA +static unsigned char * +gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa, + size_t *key_len) +{ + int p_bytes, q_bytes, g_bytes, k_bytes; + unsigned long len; + unsigned char* key; + unsigned char* p; + + const BIGNUM * p_bn; + const BIGNUM * q; + const BIGNUM * g; + const BIGNUM * pub_key; +#ifdef HAVE_OPAQUE_STRUCTS + DSA_get0_pqg(dsa, &p_bn, &q, &g); +#else + p_bn = dsa->p; + q = dsa->q; + g = dsa->g; +#endif + +#ifdef HAVE_OPAQUE_STRUCTS + DSA_get0_key(dsa, &pub_key, NULL); +#else + pub_key = dsa->pub_key; +#endif + p_bytes = BN_num_bytes(p_bn) + 1; + q_bytes = BN_num_bytes(q) + 1; + g_bytes = BN_num_bytes(g) + 1; + k_bytes = BN_num_bytes(pub_key) + 1; + + /* Key form is "ssh-dss" + p + q + g + pub_key. */ + len = 4 + 7 + 4 + p_bytes + 4 + q_bytes + 4 + g_bytes + 4 + k_bytes; + + key = LIBSSH2_ALLOC(session, len); + if (key == NULL) { + return NULL; + } + + /* Process key encoding. */ + p = key; + + _libssh2_htonu32(p, 7); /* Key type. */ + p += 4; + memcpy(p, "ssh-dss", 7); + p += 7; + + p = write_bn(p, p_bn, p_bytes); + p = write_bn(p, q, q_bytes); + p = write_bn(p, g, g_bytes); + p = write_bn(p, pub_key, k_bytes); + + *key_len = (size_t)(p - key); + return key; +} +#endif /* LIBSSH_DSA */ + +static int +gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + EVP_PKEY *pk) +{ + RSA* rsa = NULL; + unsigned char* key; + unsigned char* method_buf = NULL; + size_t key_len; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from RSA private key envelop"); + + rsa = EVP_PKEY_get1_RSA(pk); + if (rsa == NULL) { + /* Assume memory allocation error... what else could it be ? */ + goto __alloc_error; + } + + method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-rsa. */ + if (method_buf == NULL) { + goto __alloc_error; + } + + key = gen_publickey_from_rsa(session, rsa, &key_len); + if (key == NULL) { + goto __alloc_error; + } + RSA_free(rsa); + + memcpy(method_buf, "ssh-rsa", 7); + *method = method_buf; + *method_len = 7; + *pubkeydata = key; + *pubkeydata_len = key_len; + return 0; + + __alloc_error: + if (rsa != NULL) { + RSA_free(rsa); + } + if (method_buf != NULL) { + LIBSSH2_FREE(session, method_buf); + } + + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); +} + +#if LIBSSH2_DSA +static int +gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + EVP_PKEY *pk) +{ + DSA* dsa = NULL; + unsigned char* key; + unsigned char* method_buf = NULL; + size_t key_len; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from DSA private key envelop"); + + dsa = EVP_PKEY_get1_DSA(pk); + if (dsa == NULL) { + /* Assume memory allocation error... what else could it be ? */ + goto __alloc_error; + } + + method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-dss. */ + if (method_buf == NULL) { + goto __alloc_error; + } + + key = gen_publickey_from_dsa(session, dsa, &key_len); + if (key == NULL) { + goto __alloc_error; + } + DSA_free(dsa); + + memcpy(method_buf, "ssh-dss", 7); + *method = method_buf; + *method_len = 7; + *pubkeydata = key; + *pubkeydata_len = key_len; + return 0; + + __alloc_error: + if (dsa != NULL) { + DSA_free(dsa); + } + if (method_buf != NULL) { + LIBSSH2_FREE(session, method_buf); + } + + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); +} +#endif /* LIBSSH_DSA */ + +int +_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ + int st; + BIO* bp; + EVP_PKEY* pk; + int pktype; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from private key file: %s", + privatekey); + + bp = BIO_new_file(privatekey, "r"); + if (bp == NULL) { + return _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key from private key " + "file: Unable to open private key file"); + } + if (!EVP_get_cipherbyname("des")) { + /* If this cipher isn't loaded it's a pretty good indication that none + * are. I have *NO DOUBT* that there's a better way to deal with this + * ($#&%#$(%$#( Someone buy me an OpenSSL manual and I'll read up on + * it. + */ + OpenSSL_add_all_ciphers(); + } + BIO_reset(bp); + pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase); + BIO_free(bp); + + if (pk == NULL) { + return _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Wrong passphrase or invalid/unrecognized " + "private key file format"); + } + +#ifdef HAVE_OPAQUE_STRUCTS + pktype = EVP_PKEY_id(pk); +#else + pktype = pk->type; +#endif + + switch (pktype) { + case EVP_PKEY_RSA : + st = gen_publickey_from_rsa_evp( + session, method, method_len, pubkeydata, pubkeydata_len, pk); + break; + +#if LIBSSH2_DSA + case EVP_PKEY_DSA : + st = gen_publickey_from_dsa_evp( + session, method, method_len, pubkeydata, pubkeydata_len, pk); + break; +#endif /* LIBSSH_DSA */ + + default : + st = _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Unsupported private key file format"); + break; + } + + EVP_PKEY_free(pk); + return st; +} + +int +_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + int st; + BIO* bp; + EVP_PKEY* pk; + int pktype; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from private key."); + + bp = BIO_new_mem_buf((char *)privatekeydata, privatekeydata_len); + if (!bp) { + return -1; + } + if (!EVP_get_cipherbyname("des")) { + /* If this cipher isn't loaded it's a pretty good indication that none + * are. I have *NO DOUBT* that there's a better way to deal with this + * ($#&%#$(%$#( Someone buy me an OpenSSL manual and I'll read up on + * it. + */ + OpenSSL_add_all_ciphers(); + } + BIO_reset(bp); + pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase); + BIO_free(bp); + + if (pk == NULL) { + return _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Wrong passphrase or invalid/unrecognized " + "private key file format"); + } + +#ifdef HAVE_OPAQUE_STRUCTS + pktype = EVP_PKEY_id(pk); +#else + pktype = pk->type; +#endif + + switch (pktype) { + case EVP_PKEY_RSA : + st = gen_publickey_from_rsa_evp(session, method, method_len, + pubkeydata, pubkeydata_len, pk); + break; +#if LIBSSH2_DSA + case EVP_PKEY_DSA : + st = gen_publickey_from_dsa_evp(session, method, method_len, + pubkeydata, pubkeydata_len, pk); + break; +#endif /* LIBSSH_DSA */ + default : + st = _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Unsupported private key file format"); + break; + } + + EVP_PKEY_free(pk); + return st; +} + +#endif /* LIBSSH2_OPENSSL */ diff --git a/libssh2/src/openssl.h b/libssh2/src/openssl.h new file mode 100644 index 000000000..3ca71fa8a --- /dev/null +++ b/libssh2/src/openssl.h @@ -0,0 +1,293 @@ +/* Copyright (C) 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. + * + * Author: Simon Josefsson + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_MD5 +#include +#endif +#include +#include +#include +#include +#include + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) +# define HAVE_OPAQUE_STRUCTS 1 +#endif + +#ifdef OPENSSL_NO_RSA +# define LIBSSH2_RSA 0 +#else +# define LIBSSH2_RSA 1 +#endif + +#ifdef OPENSSL_NO_DSA +# define LIBSSH2_DSA 0 +#else +# define LIBSSH2_DSA 1 +#endif + +#ifdef OPENSSL_NO_MD5 +# define LIBSSH2_MD5 0 +#else +# define LIBSSH2_MD5 1 +#endif + +#ifdef OPENSSL_NO_RIPEMD +# define LIBSSH2_HMAC_RIPEMD 0 +#else +# define LIBSSH2_HMAC_RIPEMD 1 +#endif + +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES) +# define LIBSSH2_AES_CTR 1 +# define LIBSSH2_AES 1 +#else +# define LIBSSH2_AES_CTR 0 +# define LIBSSH2_AES 0 +#endif + +#ifdef OPENSSL_NO_BF +# define LIBSSH2_BLOWFISH 0 +#else +# define LIBSSH2_BLOWFISH 1 +#endif + +#ifdef OPENSSL_NO_RC4 +# define LIBSSH2_RC4 0 +#else +# define LIBSSH2_RC4 1 +#endif + +#ifdef OPENSSL_NO_CAST +# define LIBSSH2_CAST 0 +#else +# define LIBSSH2_CAST 1 +#endif + +#ifdef OPENSSL_NO_DES +# define LIBSSH2_3DES 0 +#else +# define LIBSSH2_3DES 1 +#endif + +#define _libssh2_random(buf, len) RAND_bytes ((buf), (len)) + +#define libssh2_prepare_iovec(vec, len) /* Empty. */ + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha1_ctx EVP_MD_CTX * +#else +#define libssh2_sha1_ctx EVP_MD_CTX +#endif + +/* returns 0 in case of failure */ +int _libssh2_sha1_init(libssh2_sha1_ctx *ctx); +#define libssh2_sha1_init(x) _libssh2_sha1_init(x) +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) +#define libssh2_sha1_final(ctx, out) do { \ + EVP_DigestFinal(ctx, out, NULL); \ + EVP_MD_CTX_free(ctx); \ + } while(0) +#else +#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +#endif +int _libssh2_sha1(const unsigned char *message, unsigned long len, + unsigned char *out); +#define libssh2_sha1(x,y,z) _libssh2_sha1(x,y,z) + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha256_ctx EVP_MD_CTX * +#else +#define libssh2_sha256_ctx EVP_MD_CTX +#endif + +/* returns 0 in case of failure */ +int _libssh2_sha256_init(libssh2_sha256_ctx *ctx); +#define libssh2_sha256_init(x) _libssh2_sha256_init(x) +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) +#define libssh2_sha256_final(ctx, out) do { \ + EVP_DigestFinal(ctx, out, NULL); \ + EVP_MD_CTX_free(ctx); \ + } while(0) +#else +#define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +#endif +int _libssh2_sha256(const unsigned char *message, unsigned long len, + unsigned char *out); +#define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z) + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_md5_ctx EVP_MD_CTX * +#else +#define libssh2_md5_ctx EVP_MD_CTX +#endif + +/* returns 0 in case of failure */ +int _libssh2_md5_init(libssh2_md5_ctx *ctx); +#define libssh2_md5_init(x) _libssh2_md5_init(x) +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) +#define libssh2_md5_final(ctx, out) do { \ + EVP_DigestFinal(ctx, out, NULL); \ + EVP_MD_CTX_free(ctx); \ + } while(0) +#else +#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +#endif + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_hmac_ctx HMAC_CTX * +#define libssh2_hmac_ctx_init(ctx) ctx = HMAC_CTX_new() +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_sha1(), NULL) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_md5(), NULL) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_ripemd160(), NULL) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_sha256(), NULL) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_sha512(), NULL) + +#define libssh2_hmac_update(ctx, data, datalen) \ + HMAC_Update(ctx, data, datalen) +#define libssh2_hmac_final(ctx, data) HMAC_Final(ctx, data, NULL) +#define libssh2_hmac_cleanup(ctx) HMAC_CTX_free(*(ctx)) +#else +#define libssh2_hmac_ctx HMAC_CTX +#define libssh2_hmac_ctx_init(ctx) \ + HMAC_CTX_init(&ctx) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_sha1(), NULL) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_md5(), NULL) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_ripemd160(), NULL) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_sha256(), NULL) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_sha512(), NULL) + +#define libssh2_hmac_update(ctx, data, datalen) \ + HMAC_Update(&(ctx), data, datalen) +#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL) +#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx) +#endif + +#define libssh2_crypto_init() \ + OpenSSL_add_all_algorithms(); \ + ENGINE_load_builtin_engines(); \ + ENGINE_register_all_complete() + +#define libssh2_crypto_exit() + +#define libssh2_rsa_ctx RSA + +#define _libssh2_rsa_free(rsactx) RSA_free(rsactx) + +#define libssh2_dsa_ctx DSA + + +#define _libssh2_dsa_free(dsactx) DSA_free(dsactx) + +#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void) +#ifdef HAVE_OPAQUE_STRUCTS +#define _libssh2_cipher_ctx EVP_CIPHER_CTX * +#else +#define _libssh2_cipher_ctx EVP_CIPHER_CTX +#endif + +#define _libssh2_cipher_aes256 EVP_aes_256_cbc +#define _libssh2_cipher_aes192 EVP_aes_192_cbc +#define _libssh2_cipher_aes128 EVP_aes_128_cbc +#ifdef HAVE_EVP_AES_128_CTR +#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr +#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr +#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr +#else +#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr +#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr +#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr +#endif +#define _libssh2_cipher_blowfish EVP_bf_cbc +#define _libssh2_cipher_arcfour EVP_rc4 +#define _libssh2_cipher_cast5 EVP_cast5_cbc +#define _libssh2_cipher_3des EVP_des_ede3_cbc + +#ifdef HAVE_OPAQUE_STRUCTS +#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_reset(*(ctx)) +#else +#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx) +#endif + +#define _libssh2_bn BIGNUM +#define _libssh2_bn_ctx BN_CTX +#define _libssh2_bn_ctx_new() BN_CTX_new() +#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx) +#define _libssh2_bn_init() BN_new() +#define _libssh2_bn_init_from_bin() _libssh2_bn_init() +#define _libssh2_bn_rand(bn, bits, top, bottom) BN_rand(bn, bits, top, bottom) +#define _libssh2_bn_mod_exp(r, a, p, m, ctx) BN_mod_exp(r, a, p, m, ctx) +#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val) +#define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn) +#define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val) +#define _libssh2_bn_bytes(bn) BN_num_bytes(bn) +#define _libssh2_bn_bits(bn) BN_num_bits(bn) +#define _libssh2_bn_free(bn) BN_clear_free(bn) + +const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void); +const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void); +const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void); + diff --git a/libssh2/src/os400qc3.c b/libssh2/src/os400qc3.c new file mode 100644 index 000000000..f8e46aba9 --- /dev/null +++ b/libssh2/src/os400qc3.c @@ -0,0 +1,2513 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_OS400QC3 /* compile only if we build with OS/400 QC3 library */ + +#ifdef HAVE_STDLIB_H +#include +#endif + +#include +#include +#include +#include + +#include + + +#ifdef OS400_DEBUG +/* In debug mode, all system library errors cause an exception. */ +#define set_EC_length(ec, length) ((ec).Bytes_Provided = \ + (ec).Bytes_Available = 0) +#else +#define set_EC_length(ec, length) ((ec).Bytes_Provided = (length)) +#endif + + +/* Ensure va_list operations are not on an array. */ +typedef struct { + va_list list; +} valiststr; + + +typedef int (*loadkeyproc)(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata); + +/* Public key extraction data. */ +typedef struct { + const char * method; + const unsigned char * data; + unsigned int length; +} loadpubkeydata; + + +/* Support for ASN.1 elements. */ + +typedef struct { + char * header; /* Pointer to header byte. */ + char * beg; /* Pointer to element data. */ + char * end; /* Pointer to 1st byte after element. */ + unsigned char class; /* ASN.1 element class. */ + unsigned char tag; /* ASN.1 element tag. */ + unsigned char constructed; /* Element is constructed. */ +} asn1Element; + +#define ASN1_INTEGER 2 +#define ASN1_BIT_STRING 3 +#define ASN1_OCTET_STRING 4 +#define ASN1_NULL 5 +#define ASN1_OBJ_ID 6 +#define ASN1_SEQ 16 + +#define ASN1_CONSTRUCTED 0x20 + +/* rsaEncryption OID: 1.2.840.113549.1.1.1 */ +static unsigned char OID_rsaEncryption[] = + {9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 1, 1, 1}; +static int sshrsapubkey(LIBSSH2_SESSION *session, char **sshpubkey, + asn1Element *params, asn1Element *key, + const char *method); + +#if LIBSSH2_DSA != 0 +/* dsaEncryption OID: 1.2.840.10040.4.1 */ +static unsigned char OID_dsaEncryption[] = + {7, 40 + 2, 0x86, 0x48, 0xCE, 0x38, 4, 1}; +static int sshdsapubkey(LIBSSH2_SESSION *session, char **sshpubkey, + asn1Element *params, asn1Element *key, + const char *method); +#endif + + +/* PKCS#5 support. */ + +typedef struct pkcs5params pkcs5params; +struct pkcs5params { + int cipher; /* Encryption cipher. */ + int blocksize; /* Cipher block size. */ + char mode; /* Block encryption mode. */ + char padopt; /* Pad option. */ + char padchar; /* Pad character. */ + int (*kdf)(LIBSSH2_SESSION *session, char **dk, + const unsigned char * passphrase, pkcs5params *pkcs5); + int hash; /* KDF hash algorithm. */ + size_t hashlen; /* KDF hash digest length. */ + char * salt; /* Salt. */ + size_t saltlen; /* Salt length. */ + char * iv; /* Initialization vector. */ + size_t ivlen; /* Initialization vector length. */ + int itercount; /* KDF iteration count. */ + int dklen; /* Derived key length (#bytes). */ + int effkeysize; /* RC2 effective key size (#bits) or 0. */ +}; + +typedef struct pkcs5algo pkcs5algo; +struct pkcs5algo { + const unsigned char * oid; + int (*parse)(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); + int cipher; /* Encryption cipher. */ + size_t blocksize; /* Cipher block size. */ + char mode; /* Block encryption mode. */ + char padopt; /* Pad option. */ + char padchar; /* Pad character. */ + size_t keylen; /* Key length (#bytes). */ + int hash; /* Hash algorithm. */ + size_t hashlen; /* Hash digest length. */ + size_t saltlen; /* Salt length. */ + size_t ivlen; /* Initialisation vector length. */ + int effkeysize; /* RC2 effective key size (#bits) or 0. */ +}; + +/* id-PBES2 OID: 1.2.840.113549.1.5.13 */ +static const unsigned char OID_id_PBES2[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0D +}; +static int parse_pbes2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo PBES2 = { + OID_id_PBES2, parse_pbes2, 0, 0, '\0', '\0', '\0', 0, + 0, 0, 0, 0, 0 +}; + +/* id-PBKDF2 OID: 1.2.840.113549.1.5.12 */ +static const unsigned char OID_id_PBKDF2[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C +}; +static int parse_pbkdf2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo PBKDF2 = { + OID_id_PBKDF2, parse_pbkdf2, 0, 0, '\0', '\0', '\0', + SHA_DIGEST_LENGTH, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 8, 0 +}; + +/* id-hmacWithSHA1 OID: 1.2.840.113549.2.7 */ +static const unsigned char OID_id_hmacWithSHA1[] = { + 8, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x07 +}; +static int parse_hmacWithSHA1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo hmacWithSHA1 = { + OID_id_hmacWithSHA1, parse_hmacWithSHA1, 0, 0, '\0', '\0', '\0', + SHA_DIGEST_LENGTH, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 8, 0 +}; + +/* desCBC OID: 1.3.14.3.2.7 */ +static const unsigned char OID_desCBC[] = {5, 40 + 3, 0x0E, 0x03, 0x02, 0x07}; +static int parse_iv(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo desCBC = { + OID_desCBC, parse_iv, Qc3_DES, 8, Qc3_CBC, Qc3_Pad_Counter, + '\0', 8, 0, 0, 8, 8, 0 +}; + +/* des-EDE3-CBC OID: 1.2.840.113549.3.7 */ +static const unsigned char OID_des_EDE3_CBC[] = { + 8, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07 +}; +static const pkcs5algo des_EDE3_CBC = { + OID_des_EDE3_CBC, parse_iv, Qc3_TDES, 8, Qc3_CBC, Qc3_Pad_Counter, + '\0', 24, 0, 0, 8, 8, 0 +}; + +/* rc2CBC OID: 1.2.840.113549.3.2 */ +static const unsigned char OID_rc2CBC[] = { + 8, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x02 +}; +static int parse_rc2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo rc2CBC = { + OID_rc2CBC, parse_rc2, Qc3_RC2, 8, Qc3_CBC, Qc3_Pad_Counter, + '\0', 0, 0, 0, 8, 0, 32 +}; + +/* pbeWithMD5AndDES-CBC OID: 1.2.840.113549.1.5.3 */ +static const unsigned char OID_pbeWithMD5AndDES_CBC[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x03 +}; +static int parse_pbes1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo pbeWithMD5AndDES_CBC = { + OID_pbeWithMD5AndDES_CBC, parse_pbes1, Qc3_DES, 8, Qc3_CBC, + Qc3_Pad_Counter, '\0', 8, Qc3_MD5, MD5_DIGEST_LENGTH, 8, 0, 0 +}; + +/* pbeWithMD5AndRC2-CBC OID: 1.2.840.113549.1.5.6 */ +static const unsigned char OID_pbeWithMD5AndRC2_CBC[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x06 +}; +static const pkcs5algo pbeWithMD5AndRC2_CBC = { + OID_pbeWithMD5AndRC2_CBC, parse_pbes1, Qc3_RC2, 8, Qc3_CBC, + Qc3_Pad_Counter, '\0', 0, Qc3_MD5, MD5_DIGEST_LENGTH, 8, 0, 64 +}; + +/* pbeWithSHA1AndDES-CBC OID: 1.2.840.113549.1.5.10 */ +static const unsigned char OID_pbeWithSHA1AndDES_CBC[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0A +}; +static const pkcs5algo pbeWithSHA1AndDES_CBC = { + OID_pbeWithSHA1AndDES_CBC, parse_pbes1, Qc3_DES, 8, Qc3_CBC, + Qc3_Pad_Counter, '\0', 8, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 0, 0 +}; + +/* pbeWithSHA1AndRC2-CBC OID: 1.2.840.113549.1.5.11 */ +static const unsigned char OID_pbeWithSHA1AndRC2_CBC[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0B +}; +static const pkcs5algo pbeWithSHA1AndRC2_CBC = { + OID_pbeWithSHA1AndRC2_CBC, parse_pbes1, Qc3_RC2, 8, Qc3_CBC, + Qc3_Pad_Counter, '\0', 0, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 0, 64 +}; + +/* rc5-CBC-PAD OID: 1.2.840.113549.3.9: RC5 not implemented in Qc3. */ +/* pbeWithMD2AndDES-CBC OID: 1.2.840.113549.1.5.1: MD2 not implemented. */ +/* pbeWithMD2AndRC2-CBC OID: 1.2.840.113549.1.5.4: MD2 not implemented. */ + +static const pkcs5algo * pbestable[] = { + &pbeWithMD5AndDES_CBC, + &pbeWithMD5AndRC2_CBC, + &pbeWithSHA1AndDES_CBC, + &pbeWithSHA1AndRC2_CBC, + &PBES2, + NULL +}; + +static const pkcs5algo * pbkdf2table[] = { + &PBKDF2, + NULL +}; + +static const pkcs5algo * pbes2enctable[] = { + &desCBC, + &des_EDE3_CBC, + &rc2CBC, + NULL +}; + +static const pkcs5algo * kdf2prftable[] = { + &hmacWithSHA1, + NULL +}; + + +/* Public key extraction support. */ +static struct { + unsigned char * oid; + int (*sshpubkey)(LIBSSH2_SESSION *session, char **pubkey, + asn1Element *params, asn1Element *key, + const char *method); + const char * method; +} pka[] = { +#if LIBSSH2_RSA != 0 + { OID_rsaEncryption, sshrsapubkey, "ssh-rsa" }, +#endif +#if LIBSSH2_DSA != 0 + { OID_dsaEncryption, sshdsapubkey, "ssh-dss" }, +#endif + { NULL, NULL, NULL } +}; + +/* Define ASCII strings. */ +static const char beginencprivkeyhdr[] = + "-----BEGIN ENCRYPTED PRIVATE KEY-----"; +static const char endencprivkeyhdr[] = "-----END ENCRYPTED PRIVATE KEY-----"; +static const char beginprivkeyhdr[] = "-----BEGIN PRIVATE KEY-----"; +static const char endprivkeyhdr[] = "-----END PRIVATE KEY-----"; +static const char beginrsaprivkeyhdr[] = "-----BEGIN RSA PRIVATE KEY-----"; +static const char endrsaprivkeyhdr[] = "-----END RSA PRIVATE KEY-----"; +static const char fopenrmode[] = "r"; +static const char fopenrbmode[] = "rb"; + + +/* The rest of character literals in this module are in EBCDIC. */ +#pragma convert(37) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static Qc3_Format_KEYD0100_T nulltoken = {""}; + +static int zero = 0; +static int rsaprivate[] = { Qc3_RSA_Private }; +static char anycsp[] = { Qc3_Any_CSP }; +static char binstring[] = { Qc3_Bin_String }; +static char berstring[] = { Qc3_BER_String }; +static char qc3clear[] = { Qc3_Clear }; + +static const Qus_EC_t ecnull = {0}; /* Error causes an exception. */ + +static asn1Element lastbytebitcount = { + (char *) &zero, NULL, (char *) &zero + 1 +}; + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: ASN.1 support. + * + *******************************************************************/ + +static char * +getASN1Element(asn1Element *elem, char *beg, char *end) +{ + unsigned char b; + unsigned long len; + asn1Element lelem; + + /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg' + * ending at `end'. + * Returns a pointer in source string after the parsed element, or NULL + * if an error occurs. + */ + + if (beg >= end || !*beg) + return NULL; + + /* Process header byte. */ + elem->header = beg; + b = (unsigned char) *beg++; + elem->constructed = (b & 0x20) != 0; + elem->class = (b >> 6) & 3; + b &= 0x1F; + if (b == 0x1F) + return NULL; /* Long tag values not supported here. */ + elem->tag = b; + + /* Process length. */ + if (beg >= end) + return NULL; + b = (unsigned char) *beg++; + if (!(b & 0x80)) + len = b; + else if (!(b &= 0x7F)) { + /* Unspecified length. Since we have all the data, we can determine the + * effective length by skipping element until an end element is + * found. + */ + if (!elem->constructed) + return NULL; + elem->beg = beg; + while (beg < end && *beg) { + beg = getASN1Element(&lelem, beg, end); + if (!beg) + return NULL; + } + if (beg >= end) + return NULL; + elem->end = beg; + return beg + 1; + } else if (beg + b > end) + return NULL; /* Does not fit in source. */ + else { + /* Get long length. */ + len = 0; + do { + if (len & 0xFF000000L) + return NULL; /* Lengths > 32 bits are not supported. */ + len = (len << 8) | (unsigned char) *beg++; + } while (--b); + } + if ((unsigned long) (end - beg) < len) + return NULL; /* Element data does not fit in source. */ + elem->beg = beg; + elem->end = beg + len; + return elem->end; +} + +static asn1Element * +asn1_new(unsigned int type, unsigned int length) +{ + asn1Element *e; + unsigned int hdrl = 2; + unsigned int i; + unsigned char *buf; + + e = (asn1Element *) malloc(sizeof *e); + + if (e) { + if (length >= 0x80) + for (i = length; i; i >>= 8) + hdrl++; + + buf = (unsigned char *) malloc(hdrl + length); + + if (buf) { + e->header = buf; + e->beg = buf + hdrl; + e->end = e->beg + length; + e->class = (type >> 6) & 0x03; + e->tag = type & 0x1F; + e->constructed = (type >> 5) & 0x01; + e->header[0] = type; + + if (length < 0x80) + e->header[1] = length; + else { + e->header[1] = (hdrl - 2) | 0x80; + do { + e->header[--hdrl] = length; + length >>= 8; + } while (length); + } + } else { + free((char *) e); + e = NULL; + } + } + + return e; +} + +static asn1Element * +asn1_new_from_bytes(const unsigned char *data, unsigned int length) +{ + asn1Element *e; + asn1Element te; + + getASN1Element(&te, + (unsigned char *) data, (unsigned char *) data + length); + e = asn1_new(te.tag, te.end - te.beg); + + if (e) + memcpy(e->header, data, e->end - e->header); + + return e; +} + +static void +asn1delete(asn1Element *e) +{ + if (e) { + if (e->header) + free((char *) e->header); + free((char *) e); + } +} + +static asn1Element * +asn1uint(_libssh2_bn *bn) +{ + asn1Element *e; + int bits; + int length; + unsigned char * p; + + if (!bn) + return NULL; + + bits = _libssh2_bn_bits(bn); + length = (bits + 8) >> 3; + e = asn1_new(ASN1_INTEGER, length); + + if (e) { + p = e->beg; + if (!(bits & 0x07)) + *p++ = 0; + _libssh2_bn_to_bin(bn, p); + } + + return e; +} + +static asn1Element * +asn1containerv(unsigned int type, valiststr args) +{ + valiststr va; + asn1Element *e; + asn1Element *p; + unsigned char *bp; + unsigned int length = 0; + + memcpy((char *) &va, (char *) &args, sizeof args); + while ((p = va_arg(va.list, asn1Element *))) + length += p->end - p->header; + va_end(va.list); + e = asn1_new(type, length); + if (e) { + bp = e->beg; + while ((p = va_arg(args.list, asn1Element *))) { + memcpy(bp, p->header, p->end - p->header); + bp += p->end - p->header; + } + } + return e; +} + +/* VARARGS1 */ +static asn1Element * +asn1container(unsigned int type, ...) +{ + valiststr va; + asn1Element *e; + + va_start(va.list, type); + e = asn1containerv(type, va); + va_end(va.list); + return e; +} + +static asn1Element * +asn1bytes(unsigned int type, const unsigned char *bytes, unsigned int length) +{ + asn1Element *e; + + e = asn1_new(type, length); + if (e && length) + memcpy(e->beg, bytes, length); + return e; +} + +static asn1Element * +rsapublickey(_libssh2_bn *e, _libssh2_bn *m) +{ + asn1Element *publicexponent; + asn1Element *modulus; + asn1Element *rsapubkey; + + /* Build a PKCS#1 RSAPublicKey. */ + + modulus = asn1uint(m); + publicexponent = asn1uint(e); + rsapubkey = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + modulus, publicexponent, NULL); + asn1delete(modulus); + asn1delete(publicexponent); + + if (!modulus || !publicexponent) { + asn1delete(rsapubkey); + rsapubkey = NULL; + } + + return rsapubkey; +} + +static asn1Element * +rsaprivatekey(_libssh2_bn *e, _libssh2_bn *m, _libssh2_bn *d, + _libssh2_bn *p, _libssh2_bn *q, + _libssh2_bn *exp1, _libssh2_bn *exp2, _libssh2_bn *coeff) +{ + asn1Element *version; + asn1Element *modulus; + asn1Element *publicexponent; + asn1Element *privateexponent; + asn1Element *prime1; + asn1Element *prime2; + asn1Element *exponent1; + asn1Element *exponent2; + asn1Element *coefficient; + asn1Element *rsaprivkey; + + /* Build a PKCS#1 RSAPrivateKey. */ + version = asn1bytes(ASN1_INTEGER, "\0", 1); + modulus = asn1uint(m); + publicexponent = asn1uint(e); + privateexponent = asn1uint(d); + prime1 = asn1uint(p); + prime2 = asn1uint(q); + exponent1 = asn1uint(exp1); + exponent2 = asn1uint(exp2); + coefficient = asn1uint(coeff); + rsaprivkey = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, version, modulus, + publicexponent, privateexponent, prime1, prime2, + exponent1, exponent2, coefficient, NULL); + asn1delete(version); + asn1delete(modulus); + asn1delete(publicexponent); + asn1delete(privateexponent); + asn1delete(prime1); + asn1delete(prime2); + asn1delete(exponent1); + asn1delete(exponent2); + asn1delete(coefficient); + + if (!version || !modulus || !publicexponent || !privateexponent || + !prime1 || !prime2 || !exponent1 || !exponent2 || !coefficient) { + asn1delete(rsaprivkey); + rsaprivkey = NULL; + } + + return rsaprivkey; +} + +static asn1Element * +subjectpublickeyinfo(asn1Element *pubkey, const unsigned char *algo, + asn1Element *parameters) +{ + asn1Element *subjpubkey; + asn1Element *algorithm; + asn1Element *algorithmid; + asn1Element *subjpubkeyinfo; + unsigned int algosize = *algo++; + + algorithm = asn1bytes(ASN1_OBJ_ID, algo, algosize); + algorithmid = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + algorithm, parameters, NULL); + subjpubkey = asn1container(ASN1_BIT_STRING, &lastbytebitcount, + pubkey, NULL); + subjpubkeyinfo = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + algorithmid, subjpubkey, NULL); + asn1delete(algorithm); + asn1delete(algorithmid); + asn1delete(subjpubkey); + if (!algorithm || !algorithmid || !subjpubkey) { + asn1delete(subjpubkeyinfo); + subjpubkeyinfo = NULL; + } + return subjpubkeyinfo; +} + +static asn1Element * +rsasubjectpublickeyinfo(asn1Element *pubkey) +{ + asn1Element *parameters; + asn1Element *subjpubkeyinfo; + + parameters = asn1bytes(ASN1_NULL, NULL, 0); + subjpubkeyinfo = subjectpublickeyinfo(pubkey, + OID_rsaEncryption, parameters); + asn1delete(parameters); + if (!parameters) { + asn1delete(subjpubkeyinfo); + subjpubkeyinfo = NULL; + } + return subjpubkeyinfo; +} + +static asn1Element * +privatekeyinfo(asn1Element *privkey, const unsigned char *algo, + asn1Element *parameters) +{ + asn1Element *version; + asn1Element *privatekey; + asn1Element *algorithm; + asn1Element *privatekeyalgorithm; + asn1Element *privkeyinfo; + unsigned int algosize = *algo++; + + /* Build a PKCS#8 PrivateKeyInfo. */ + version = asn1bytes(ASN1_INTEGER, "\0", 1); + algorithm = asn1bytes(ASN1_OBJ_ID, algo, algosize); + privatekeyalgorithm = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + algorithm, parameters, NULL); + privatekey = asn1container(ASN1_OCTET_STRING, privkey, NULL); + privkeyinfo = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, version, + privatekeyalgorithm, privatekey, NULL); + asn1delete(version); + asn1delete(algorithm); + asn1delete(privatekeyalgorithm); + if (!version || !algorithm || !privatekeyalgorithm) { + asn1delete(privkeyinfo); + privkeyinfo = NULL; + } + return privkeyinfo; +} + +static asn1Element * +rsaprivatekeyinfo(asn1Element *privkey) +{ + asn1Element *parameters; + asn1Element *privkeyinfo; + + parameters = asn1bytes(ASN1_NULL, NULL, 0); + privkeyinfo = privatekeyinfo(privkey, OID_rsaEncryption, parameters); + asn1delete(parameters); + if (!parameters) { + asn1delete(privkeyinfo); + privkeyinfo = NULL; + } + return privkeyinfo; +} + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: big numbers support. + * + *******************************************************************/ + + +_libssh2_bn * +_libssh2_bn_init(void) +{ + _libssh2_bn *bignum; + + bignum = (_libssh2_bn *) malloc(sizeof *bignum); + if (bignum) { + bignum->bignum = NULL; + bignum->length = 0; + } + + return bignum; +} + +void +_libssh2_bn_free(_libssh2_bn *bn) +{ + if (bn) { + if (bn->bignum) { +#ifdef LIBSSH2_CLEAR_MEMORY + if (bn->length) + memset((char *) bn->bignum, 0, bn->length); +#endif + free(bn->bignum); + } + + free((char *) bn); + } +} + +static int +_libssh2_bn_resize(_libssh2_bn *bn, size_t newlen) +{ + unsigned char *bignum; + + if (!bn) + return -1; + if (newlen == bn->length) + return 0; + + if (!bn->bignum) + bignum = (unsigned char *) malloc(newlen); + else { +#ifdef LIBSSH2_CLEAR_MEMORY + if (newlen < bn->length) + memset((char *) bn->bignum + newlen, 0, bn->length - newlen); +#endif + if (!newlen) { + free((char *) bn->bignum); + bn->bignum = NULL; + bn->length = 0; + return 0; + } + bignum = (unsigned char *) realloc((char *) bn->bignum, newlen); + } + + if (!bignum) + return -1; + + if (newlen > bn->length) + memset((char *) bignum + bn->length, 0, newlen - bn->length); + + bn->bignum = bignum; + bn->length = newlen; + return 0; +} + +unsigned long +_libssh2_bn_bits(_libssh2_bn *bn) +{ + unsigned int i; + unsigned char b; + + if (bn && bn->bignum) { + for (i = bn->length; i--;) + if ((b = bn->bignum[i])) { + i *= 8; + do { + i++; + } while (b >>= 1); + return i; + } + } + + return 0; +} + +int +_libssh2_bn_from_bin(_libssh2_bn *bn, int len, const unsigned char *val) +{ + int i; + + if (!bn || (len && !val)) + return -1; + + for (; len && !*val; len--) + val++; + + if (_libssh2_bn_resize(bn, len)) + return -1; + + for (i = len; i--;) + bn->bignum[i] = *val++; + + return 0; +} + +int +_libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val) +{ + val = htonl(val); + return _libssh2_bn_from_bin(bn, sizeof val, (unsigned char *) &val); +} + +int +_libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val) +{ + int i; + + if (!bn || !val) + return -1; + + for (i = bn->length; i--;) + *val++ = bn->bignum[i]; + + return 0; +} + +static int +_libssh2_bn_from_bn(_libssh2_bn *to, _libssh2_bn *from) +{ + int i; + + if (!to || !from) + return -1; + + if (_libssh2_bn_resize(to, from->length)) + return -1; + + for (i = to->length; i--;) + to->bignum[i] = from->bignum[i]; + + return 0; +} + +void +_libssh2_random(unsigned char *buf, int len) +{ + Qc3GenPRNs(buf, len, + Qc3PRN_TYPE_NORMAL, Qc3PRN_NO_PARITY, (char *) &ecnull); +} + +int +_libssh2_bn_rand(_libssh2_bn *bn, int bits, int top, int bottom) +{ + int len; + int i; + + if (!bn || bits <= 0) + return -1; + len = (bits + 7) >> 3; + if (_libssh2_bn_resize(bn, len)) + return -1; + _libssh2_random(bn->bignum, len); + i = ((bits - 1) & 07) + 1; + bn->bignum[len - 1] &= (1 << i) - 1; + switch (top) { + case 1: + if (bits > 1) + if (i > 1) + bn->bignum[len - 1] |= 1 << (i - 2); + else + bn->bignum[len - 2] |= 0x80; + /* Fall into. */ + case 0: + bn->bignum[len - 1] |= 1 << (i - 1); + break; + } + if (bottom) + *bn->bignum |= 0x01; + return 0; +} + +static int +_libssh2_bn_lshift(_libssh2_bn *bn) +{ + int i; + int c = 0; + + if (!bn) + return -1; + + if (_libssh2_bn_resize(bn, (_libssh2_bn_bits(bn) + 8) >> 3)) + return -1; + + for (i = 0; i < bn->length; i++) { + if (bn->bignum[i] & 0x80) + c |= 0x02; + bn->bignum[i] = (bn->bignum[i] << 1) | (c & 0x01); + c >>= 1; + } + + return 0; +} + +static int +_libssh2_bn_rshift(_libssh2_bn *bn) +{ + int i; + int c = 0; + + if (!bn) + return -1; + + for (i = bn->length; i--;) { + if (bn->bignum[i] & 0x01) + c |= 0x100; + bn->bignum[i] = (bn->bignum[i] >> 1) | (c & 0x80); + c >>= 1; + } + + if (_libssh2_bn_resize(bn, (_libssh2_bn_bits(bn) + 7) >> 3)) + return -1; + + return 0; +} + +static void +_libssh2_bn_swap(_libssh2_bn *bn1, _libssh2_bn *bn2) +{ + _libssh2_bn t = *bn1; + + *bn1 = *bn2; + *bn2 = t; +} + +static int +_libssh2_bn_subtract(_libssh2_bn *d, _libssh2_bn *bn1, _libssh2_bn *bn2) +{ + int c = 0; + int i; + + if (bn1->length < bn2->length) + return -1; + + if (_libssh2_bn_resize(d, bn1->length)) + return -1; + + for (i = 0; i < bn2->length; i++) { + c += (int) bn1->bignum[i] - (int) bn2->bignum[i]; + d->bignum[i] = c; + c = c < 0? -1: 0; + } + + for (; c && i < bn1->length; i++) { + c += (int) bn1->bignum[i]; + d->bignum[i] = c; + c = c < 0? -1: 0; + } + + if (_libssh2_bn_resize(d, (_libssh2_bn_bits(d) + 7) >> 3)) + return -1; + + return c; +} + +int +_libssh2_os400qc3_bn_mod_exp(_libssh2_bn *r, _libssh2_bn *a, _libssh2_bn *p, + _libssh2_bn *m) +{ + _libssh2_bn *mp; + _libssh2_bn *rp; + asn1Element *rsapubkey; + asn1Element *subjpubkeyinfo; + unsigned char *av; + unsigned char *rv; + char *keydbuf; + Qc3_Format_ALGD0400_T algd; + Qc3_Format_KEYD0200_T *keyd; + Qus_EC_t errcode; + int sc; + int outlen; + int ret = -1; + + /* There is no support for this function in the Qc3 crypto-library. + Since a RSA encryption performs this function, we can emulate it + by creating an RSA public key in ASN.1 SubjectPublicKeyInfo format + from p (exponent) and m (modulus) and encrypt a with this key. The + encryption output is the function result. + Problem: the Qc3EncryptData procedure only succeeds if the data bit + count is less than the modulus bit count. To satisfy this condition, + we multiply the modulus by a power of two and adjust the result + accordingly. */ + + if (!r || !a || !p) + return ret; + + mp = _libssh2_bn_init(); + if (!mp) + return ret; + if (_libssh2_bn_from_bn(mp, m)) { + _libssh2_bn_free(mp); + return ret; + } + for (sc = 0; _libssh2_bn_bits(mp) <= 8 * a->length; sc++) + if (_libssh2_bn_lshift(mp)) { + _libssh2_bn_free(mp); + return ret; + } + + rsapubkey = rsapublickey(p, mp); + subjpubkeyinfo = rsasubjectpublickeyinfo(rsapubkey); + asn1delete(rsapubkey); + + if (!rsapubkey || !subjpubkeyinfo) { + asn1delete(rsapubkey); + asn1delete(subjpubkeyinfo); + _libssh2_bn_free(mp); + return ret; + } + + av = (unsigned char *) alloca(a->length); + rv = (unsigned char *) alloca(mp->length); + keydbuf = alloca(sizeof *keyd + + subjpubkeyinfo->end - subjpubkeyinfo->header); + + if (av && rv && keydbuf) { + _libssh2_bn_to_bin(a, av); + algd.Public_Key_Alg = Qc3_RSA; + algd.PKA_Block_Format = Qc3_Zero_Pad; + memset(algd.Reserved, 0, sizeof algd.Reserved); + algd.Signing_Hash_Alg = 0; + keyd = (Qc3_Format_KEYD0200_T *) keydbuf; + keyd->Key_Type = Qc3_RSA_Public; + keyd->Key_String_Len = subjpubkeyinfo->end - subjpubkeyinfo->header; + keyd->Key_Format = Qc3_BER_String; + memset(keyd->Reserved, 0, sizeof keyd->Reserved); + memcpy(keydbuf + sizeof *keyd, subjpubkeyinfo->header, + keyd->Key_String_Len); + set_EC_length(errcode, sizeof errcode); + Qc3EncryptData(av, (int *) &a->length, Qc3_Data, (char *) &algd, + Qc3_Alg_Public_Key, keydbuf, Qc3_Key_Parms, anycsp, + NULL, rv, (int *) &mp->length, &outlen, &errcode); + if (!errcode.Bytes_Available) { + _libssh2_bn_from_bin(r, outlen, rv); + if (!sc) + ret = 0; + else { + rp = _libssh2_bn_init(); + if (rp) { + do { + _libssh2_bn_rshift(mp); + if (!_libssh2_bn_subtract(rp, r, mp)) + _libssh2_bn_swap(r, rp); + } while (--sc); + _libssh2_bn_free(rp); + ret = 0; + } + } + } + } + asn1delete(subjpubkeyinfo); + _libssh2_bn_free(mp); + return ret; +} + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: crypto context support. + * + *******************************************************************/ + +static _libssh2_os400qc3_crypto_ctx * +libssh2_init_crypto_ctx(_libssh2_os400qc3_crypto_ctx *ctx) +{ + if (!ctx) + ctx = (_libssh2_os400qc3_crypto_ctx *) malloc(sizeof *ctx); + + if (ctx) { + memset((char *) ctx, 0, sizeof *ctx); + ctx->hash.Final_Op_Flag = Qc3_Continue; + } + + return ctx; +} + +static int +null_token(const char *token) +{ + return !memcmp(token, nulltoken.Key_Context_Token, + sizeof nulltoken.Key_Context_Token); +} + +void +_libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x) +{ + if (!x) + return; + if (!null_token(x->hash.Alg_Context_Token)) { + Qc3DestroyAlgorithmContext(x->hash.Alg_Context_Token, (char *) &ecnull); + memset(x->hash.Alg_Context_Token, 0, sizeof x->hash.Alg_Context_Token); + } + if (!null_token(x->key.Key_Context_Token)) { + Qc3DestroyKeyContext(x->key.Key_Context_Token, (char *) &ecnull); + memset(x->key.Key_Context_Token, 0, sizeof x->key.Key_Context_Token); + } + if (x->kek) { + _libssh2_os400qc3_crypto_dtor(x->kek); + free((char *) x->kek); + x->kek = NULL; + } +} + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: hash algorithms support. + * + *******************************************************************/ + +int +libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, unsigned int algorithm) +{ + Qc3_Format_ALGD0500_T algd; + Qus_EC_t errcode; + + if (!x) + return 0; + + memset((char *) x, 0, sizeof *x); + x->Final_Op_Flag = Qc3_Continue; + algd.Hash_Alg = algorithm; + set_EC_length(errcode, sizeof errcode); + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Hash, + x->Alg_Context_Token, &errcode); + return errcode.Bytes_Available? 0: 1; +} + +void +libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, + unsigned char *data, int len) +{ + char dummy[64]; + + ctx->Final_Op_Flag = Qc3_Continue; + Qc3CalculateHash((char *) data, &len, Qc3_Data, (char *) ctx, + Qc3_Alg_Token, anycsp, NULL, dummy, (char *) &ecnull); +} + +void +libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, unsigned char *out) +{ + char data; + + ctx->Final_Op_Flag = Qc3_Final; + Qc3CalculateHash(&data, &zero, Qc3_Data, (char *) ctx, Qc3_Alg_Token, + anycsp, NULL, (char *) out, (char *) &ecnull); + Qc3DestroyAlgorithmContext(ctx->Alg_Context_Token, (char *) &ecnull); + memset(ctx->Alg_Context_Token, 0, sizeof ctx->Alg_Context_Token); +} + +int +libssh2_os400qc3_hash(const unsigned char *message, unsigned long len, + unsigned char *out, unsigned int algo) +{ + Qc3_Format_ALGD0100_T ctx; + + if (!libssh2_os400qc3_hash_init(&ctx, algo)) + return 1; + + libssh2_os400qc3_hash_update(&ctx, (unsigned char *) message, len); + libssh2_os400qc3_hash_final(&ctx, out); + return 0; +} + +void +libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *ctx, + int algo, size_t minkeylen, void *key, int keylen) +{ + if (keylen < minkeylen) { + char *lkey = alloca(minkeylen); + + /* Pad key with zeroes if too short. */ + if (!lkey) + return; + memcpy(lkey, (char *) key, keylen); + memset(lkey + keylen, 0, minkeylen - keylen); + key = (void *) lkey; + keylen = minkeylen; + } + libssh2_os400qc3_hash_init(&ctx->hash, algo); + Qc3CreateKeyContext((char *) key, &keylen, binstring, &algo, qc3clear, + NULL, NULL, ctx->key.Key_Context_Token, + (char *) &ecnull); +} + +void +libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx, + unsigned char *data, int len) +{ + char dummy[64]; + + ctx->hash.Final_Op_Flag = Qc3_Continue; + Qc3CalculateHMAC((char *) data, &len, Qc3_Data, (char *) &ctx->hash, + Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, + anycsp, NULL, dummy, (char *) &ecnull); +} + +void +libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx, + unsigned char *out) +{ + char data; + + ctx->hash.Final_Op_Flag = Qc3_Final; + Qc3CalculateHMAC((char *) data, &zero, Qc3_Data, (char *) &ctx->hash, + Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, + anycsp, NULL, (char *) out, (char *) &ecnull); +} + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: cipher algorithms support. + * + *******************************************************************/ + +int +_libssh2_cipher_init(_libssh2_cipher_ctx *h, _libssh2_cipher_type(algo), + unsigned char *iv, unsigned char *secret, int encrypt) +{ + Qc3_Format_ALGD0200_T algd; + Qus_EC_t errcode; + + (void) encrypt; + + if (!h) + return -1; + + libssh2_init_crypto_ctx(h); + algd.Block_Cipher_Alg = algo.algo; + algd.Block_Length = algo.size; + algd.Mode = algo.mode; + algd.Pad_Option = Qc3_No_Pad; + algd.Pad_Character = 0; + algd.Reserved = 0; + algd.MAC_Length = 0; + algd.Effective_Key_Size = 0; + memset(algd.Init_Vector, 0 , sizeof algd.Init_Vector); + if (algo.mode != Qc3_ECB && algo.size) + memcpy(algd.Init_Vector, iv, algo.size); + set_EC_length(errcode, sizeof errcode); + Qc3CreateAlgorithmContext((char *) &algd, algo.fmt, + h->hash.Alg_Context_Token, &errcode); + if (errcode.Bytes_Available) + return -1; + Qc3CreateKeyContext((char *) secret, &algo.keylen, binstring, + &algo.algo, qc3clear, NULL, NULL, + h->key.Key_Context_Token, (char *) &errcode); + if (errcode.Bytes_Available) { + _libssh2_os400qc3_crypto_dtor(h); + return -1; + } + + return 0; +} + +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blocksize) +{ + Qus_EC_t errcode; + int outlen; + int blksize = blocksize; + + (void) algo; + + set_EC_length(errcode, sizeof errcode); + if (encrypt) + Qc3EncryptData((char *) block, &blksize, Qc3_Data, + ctx->hash.Alg_Context_Token, Qc3_Alg_Token, + ctx->key.Key_Context_Token, Qc3_Key_Token, anycsp, NULL, + (char *) block, &blksize, &outlen, (char *) &errcode); + else + Qc3DecryptData((char *) block, &blksize, + ctx->hash.Alg_Context_Token, Qc3_Alg_Token, + ctx->key.Key_Context_Token, Qc3_Key_Token, anycsp, NULL, + (char *) block, &blksize, &outlen, (char *) &errcode); + + return errcode.Bytes_Available? -1: 0; +} + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: RSA support. + * + *******************************************************************/ + +int +_libssh2_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, unsigned long elen, + const unsigned char *ndata, unsigned long nlen, + const unsigned char *ddata, unsigned long dlen, + const unsigned char *pdata, unsigned long plen, + const unsigned char *qdata, unsigned long qlen, + const unsigned char *e1data, unsigned long e1len, + const unsigned char *e2data, unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen) +{ + libssh2_rsa_ctx *ctx; + _libssh2_bn *e = _libssh2_bn_init_from_bin(); + _libssh2_bn *n = _libssh2_bn_init_from_bin(); + _libssh2_bn *d = NULL; + _libssh2_bn *p = NULL; + _libssh2_bn *q = NULL; + _libssh2_bn *e1 = NULL; + _libssh2_bn *e2 = NULL; + _libssh2_bn *coeff = NULL; + asn1Element *key = NULL; + asn1Element *structkey = NULL; + Qc3_Format_ALGD0400_T algd; + Qus_EC_t errcode; + int keytype; + int ret = 0; + int i; + + ctx = libssh2_init_crypto_ctx(NULL); + if (!ctx) + ret = -1; + if (!ret) { + _libssh2_bn_from_bin(e, elen, edata); + _libssh2_bn_from_bin(n, nlen, ndata); + if (!e || !n) + ret = -1; + } + if (!ret && ddata) { + /* Private key. */ + d = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(d, dlen, ddata); + p = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(p, plen, pdata); + q = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(q, qlen, qdata); + e1 = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(e1, e1len, e1data); + e2 = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(e2, e2len, e2data); + coeff = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(coeff, coefflen, coeffdata); + if (!d || !p || !q ||!e1 || !e2 || !coeff) + ret = -1; + + if (!ret) { + /* Build a PKCS#8 private key. */ + key = rsaprivatekey(e, n, d, p, q, e1, e2, coeff); + structkey = rsaprivatekeyinfo(key); + } + keytype = Qc3_RSA_Private; + } else if (!ret) { + key = rsapublickey(e, n); + structkey = rsasubjectpublickeyinfo(key); + keytype = Qc3_RSA_Public; + } + if (!key || !structkey) + ret = -1; + + set_EC_length(errcode, sizeof errcode); + + if (!ret) { + /* Create the algorithm context. */ + algd.Public_Key_Alg = Qc3_RSA; + algd.PKA_Block_Format = Qc3_PKCS1_01; + memset(algd.Reserved, 0, sizeof algd.Reserved); + algd.Signing_Hash_Alg = Qc3_SHA1; + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Public_Key, + ctx->hash.Alg_Context_Token, &errcode); + if (errcode.Bytes_Available) + ret = -1; + ctx->hash.Final_Op_Flag = Qc3_Continue; + } + + /* Create the key context. */ + if (!ret) { + i = structkey->end - structkey->header; + Qc3CreateKeyContext(structkey->header, &i, berstring, &keytype, + qc3clear, NULL, NULL, ctx->key.Key_Context_Token, + (char *) &errcode); + if (errcode.Bytes_Available) + ret = -1; + } + + _libssh2_bn_free(e); + _libssh2_bn_free(n); + _libssh2_bn_free(d); + _libssh2_bn_free(p); + _libssh2_bn_free(q); + _libssh2_bn_free(e1); + _libssh2_bn_free(e2); + _libssh2_bn_free(coeff); + asn1delete(key); + asn1delete(structkey); + if (ret && ctx) { + _libssh2_rsa_free(ctx); + ctx = NULL; + } + *rsa = ctx; + return ret; +} + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: PKCS#5 supplement. + * + *******************************************************************/ + +static int +oidcmp(const asn1Element *e, const unsigned char *oid) +{ + int i = e->end - e->beg - *oid++; + + if (*e->header != ASN1_OBJ_ID) + return -2; + if (!i) + i = memcmp(e->beg, oid, oid[-1]); + return i; +} + +static int +asn1getword(asn1Element *e, unsigned long *v) +{ + unsigned long a; + const unsigned char *cp; + + if (*e->header != ASN1_INTEGER) + return -1; + for (cp = e->beg; cp < e->end && !*cp; cp++) + ; + if (e->end - cp > sizeof a) + return -1; + for (a = 0; cp < e->end; cp++) + a = (a << 8) | *cp; + *v = a; + return 0; +} + +static int +pbkdf1(LIBSSH2_SESSION *session, char **dk, const unsigned char * passphrase, + pkcs5params *pkcs5) +{ + int i; + Qc3_Format_ALGD0100_T hctx; + int len = pkcs5->saltlen; + char *data = (char *) pkcs5->salt; + + *dk = NULL; + if (pkcs5->dklen > pkcs5->hashlen) + return -1; + + /* Allocate the derived key buffer. */ + if (!(*dk = LIBSSH2_ALLOC(session, pkcs5->hashlen))) + return -1; + + /* Initial hash. */ + libssh2_os400qc3_hash_init(&hctx, pkcs5->hash); + libssh2_os400qc3_hash_update(&hctx, (unsigned char *) passphrase, + strlen(passphrase)); + hctx.Final_Op_Flag = Qc3_Final; + Qc3CalculateHash((char *) pkcs5->salt, &len, Qc3_Data, (char *) &hctx, + Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull); + + /* Iterate. */ + len = pkcs5->hashlen; + for (i = 1; i < pkcs5->itercount; i++) + Qc3CalculateHash((char *) *dk, &len, Qc3_Data, (char *) &hctx, + Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull); + + /* Special stuff for PBES1: split derived key into 8-byte key and 8-byte + initialization vector. */ + pkcs5->dklen = 8; + pkcs5->ivlen = 8; + pkcs5->iv = *dk + 8; + + /* Clean-up and exit. */ + Qc3DestroyAlgorithmContext(hctx.Alg_Context_Token, (char *) &ecnull); + return 0; +} + +static int +pbkdf2(LIBSSH2_SESSION *session, char **dk, const unsigned char * passphrase, + pkcs5params *pkcs5) +{ + size_t i; + size_t k; + int j; + int l; + uint32_t ni; + unsigned long long t; + char *mac; + char *buf; + _libssh2_os400qc3_crypto_ctx hctx; + + *dk = NULL; + t = ((unsigned long long) pkcs5->dklen + pkcs5->hashlen - 1) / + pkcs5->hashlen; + if (t > 0xFFFFFFFF) + return -1; + mac = alloca(pkcs5->hashlen); + if (!mac) + return -1; + + /* Allocate the derived key buffer. */ + l = t; + if (!(buf = LIBSSH2_ALLOC(session, l * pkcs5->hashlen))) + return -1; + *dk = buf; + + /* Create an HMAC context for our computations. */ + libssh2_os400qc3_hmac_init(&hctx, pkcs5->hash, pkcs5->hashlen, + (void *) passphrase, strlen(passphrase)); + + /* Process each hLen-size blocks. */ + for (i = 1; i <= l; i++) { + ni = htonl(i); + libssh2_os400qc3_hmac_update(&hctx, pkcs5->salt, pkcs5->saltlen); + libssh2_os400qc3_hmac_update(&hctx, (char *) &ni, sizeof ni); + libssh2_os400qc3_hmac_final(&hctx, mac); + memcpy(buf, mac, pkcs5->hashlen); + for (j = 1; j < pkcs5->itercount; j++) { + libssh2_os400qc3_hmac_update(&hctx, mac, pkcs5->hashlen); + libssh2_os400qc3_hmac_final(&hctx, mac); + for (k = 0; k < pkcs5->hashlen; k++) + buf[k] ^= mac[k]; + } + buf += pkcs5->hashlen; + } + + /* Computation done. Release HMAC context. */ + _libssh2_os400qc3_crypto_dtor(&hctx); + return 0; +} + +static int +parse_pkcs5_algorithm(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + asn1Element *algid, pkcs5algo **algotable) +{ + asn1Element oid; + asn1Element param; + char *cp; + + cp = getASN1Element(&oid, algid->beg, algid->end); + if (!cp || *oid.header != ASN1_OBJ_ID) + return -1; + param.header = NULL; + if (cp < algid->end) + cp = getASN1Element(¶m, cp, algid->end); + if (cp != algid->end) + return -1; + for (; *algotable; algotable++) + if (!oidcmp(&oid, (*algotable)->oid)) + return (*(*algotable)->parse)(session, pkcs5, *algotable, + param.header? ¶m: NULL); + return -1; +} + +static int +parse_pbes2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + asn1Element keyDerivationFunc; + asn1Element encryptionScheme; + char *cp; + + if (!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&keyDerivationFunc, param->beg, param->end); + if (!cp || *keyDerivationFunc.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if (getASN1Element(&encryptionScheme, cp, param->end) != param->end || + *encryptionScheme.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if (parse_pkcs5_algorithm(session, pkcs5, &encryptionScheme, pbes2enctable)) + return -1; + if (parse_pkcs5_algorithm(session, pkcs5, &keyDerivationFunc, pbkdf2table)) + return -1; + return 0; +} + +static int +parse_pbkdf2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + asn1Element salt; + asn1Element iterationCount; + asn1Element keyLength; + asn1Element prf; + unsigned long itercount; + char *cp; + + if (!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&salt, param->beg, param->end); + /* otherSource not supported. */ + if (!cp || *salt.header != ASN1_OCTET_STRING) + return -1; + cp = getASN1Element(&iterationCount, cp, param->end); + if (!cp || *iterationCount.header != ASN1_INTEGER) + return -1; + keyLength.header = prf.header = NULL; + if (cp < param->end) { + cp = getASN1Element(&prf, cp, param->end); + if (!cp) + return -1; + if (*prf.header == ASN1_INTEGER) { + keyLength = prf; + prf.header = NULL; + if (cp < param->end) + cp = getASN1Element(&prf, cp, param->end); + } + if (cp != param->end) + return -1; + } + pkcs5->hash = algo->hash; + pkcs5->hashlen = algo->hashlen; + if (prf.header) { + if (*prf.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if (parse_pkcs5_algorithm(session, pkcs5, &prf, kdf2prftable)) + return -1; + } + pkcs5->saltlen = salt.end - salt.beg; + pkcs5->salt = salt.beg; + if (asn1getword(&iterationCount, &itercount) || + !itercount || itercount > 100000) + return -1; + pkcs5->itercount = itercount; + pkcs5->kdf = pbkdf2; + return 0; +} + +static int +parse_hmacWithSHA1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + if (!param || *param->header != ASN1_NULL) + return -1; + pkcs5->hash = algo->hash; + pkcs5->hashlen = algo->hashlen; + return 0; +} + +static int +parse_iv(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + if (!param || *param->header != ASN1_OCTET_STRING || + param->end - param->beg != algo->ivlen) + return -1; + pkcs5->cipher = algo->cipher; + pkcs5->blocksize = algo->blocksize; + pkcs5->mode = algo->mode; + pkcs5->padopt = algo->padopt; + pkcs5->padchar = algo->padchar; + pkcs5->dklen = algo->keylen; + pkcs5->ivlen = algo->ivlen; + pkcs5->iv = param->beg; + return 0; +} + +static int +parse_rc2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + asn1Element iv; + unsigned long effkeysize; + char *cp; + + if (!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&iv, param->beg, param->end); + if (!cp) + return -1; + effkeysize = algo->effkeysize; + if (*iv.header == ASN1_INTEGER) { + if (asn1getword(&iv, &effkeysize) || effkeysize > 1024) + return -1; + + cp = getASN1Element(&iv, cp, param->end); + if (effkeysize < 256) + switch (effkeysize) { + case 160: + effkeysize = 40; + case 120: + effkeysize = 64; + case 58: + effkeysize = 128; + break; + default: + return -1; + } + } + if (effkeysize > 1024 || cp != param->end || + *iv.header != ASN1_OCTET_STRING || iv.end - iv.beg != algo->ivlen) + return -1; + pkcs5->cipher = algo->cipher; + pkcs5->blocksize = algo->blocksize; + pkcs5->mode = algo->mode; + pkcs5->padopt = algo->padopt; + pkcs5->padchar = algo->padchar; + pkcs5->ivlen = algo->ivlen; + pkcs5->iv = iv.beg; + pkcs5->effkeysize = effkeysize; + pkcs5->dklen = (effkeysize + 8 - 1) / 8; + return 0; +} + +static int +parse_pbes1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + asn1Element salt; + asn1Element iterationCount; + unsigned long itercount; + char *cp; + + if (!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + + cp = getASN1Element(&salt, param->beg, param->end); + if (!cp || *salt.header != ASN1_OCTET_STRING || + salt.end - salt.beg != algo->saltlen) + return -1; + if (getASN1Element(&iterationCount, cp, param->end) != param->end || + *iterationCount.header != ASN1_INTEGER) + return -1; + if (asn1getword(&iterationCount, &itercount) || + !itercount || itercount > 100000) + return -1; + pkcs5->cipher = algo->cipher; + pkcs5->blocksize = algo->blocksize; + pkcs5->mode = algo->mode; + pkcs5->padopt = algo->padopt; + pkcs5->padchar = algo->padchar; + pkcs5->hash = algo->hash; + pkcs5->hashlen = algo->hashlen; + pkcs5->dklen = 16; + pkcs5->saltlen = algo->saltlen; + pkcs5->effkeysize = algo->effkeysize; + pkcs5->salt = salt.beg; + pkcs5->kdf = pbkdf1; + pkcs5->itercount = itercount; + return 0; +} + +static int +pkcs8kek(LIBSSH2_SESSION *session, _libssh2_os400qc3_crypto_ctx **ctx, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, asn1Element *privkeyinfo) +{ + asn1Element encprivkeyinfo; + asn1Element pkcs5alg; + pkcs5params pkcs5; + size_t pplen; + char *cp; + unsigned long t; + int i; + char *dk = NULL; + Qc3_Format_ALGD0200_T algd; + Qus_EC_t errcode; + + /* Determine if the PKCS#8 data is encrypted and, if so, set-up a + key encryption key and algorithm in context. + Return 1 if encrypted, 0, if not, -1 if error. */ + + *ctx = NULL; + privkeyinfo->beg = (char *) data; + privkeyinfo->end = privkeyinfo->beg + datalen; + + /* If no passphrase is given, it cannot be an encrypted key. */ + if (!passphrase || !*passphrase) + return 0; + + /* Parse PKCS#8 data, checking if ASN.1 format is PrivateKeyInfo or + EncryptedPrivateKeyInfo. */ + if (getASN1Element(&encprivkeyinfo, privkeyinfo->beg, privkeyinfo->end) != + (char *) data + datalen || + *encprivkeyinfo.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&pkcs5alg, encprivkeyinfo.beg, encprivkeyinfo.end); + if (!cp) + return -1; + + switch (*pkcs5alg.header) { + case ASN1_INTEGER: /* Version. */ + return 0; /* This is a PrivateKeyInfo --> not encrypted. */ + case ASN1_SEQ | ASN1_CONSTRUCTED: /* AlgorithIdentifier. */ + break; /* This is an EncryptedPrivateKeyInfo --> encrypted. */ + default: + return -1; /* Unrecognized: error. */ + } + + /* Get the encrypted key data. */ + if (getASN1Element(privkeyinfo, cp, encprivkeyinfo.end) != + encprivkeyinfo.end || *privkeyinfo->header != ASN1_OCTET_STRING) + return -1; + + /* PKCS#5: parse the PBES AlgorithmIdentifier and recursively get all + encryption parameters. */ + memset((char *) &pkcs5, 0, sizeof pkcs5); + if (parse_pkcs5_algorithm(session, &pkcs5, &pkcs5alg, pbestable)) + return -1; + + /* Compute the derived key. */ + if ((*pkcs5.kdf)(session, &dk, passphrase, &pkcs5)) + return -1; + + /* Prepare the algorithm descriptor. */ + memset((char *) &algd, 0, sizeof algd); + algd.Block_Cipher_Alg = pkcs5.cipher; + algd.Block_Length = pkcs5.blocksize; + algd.Mode = pkcs5.mode; + algd.Pad_Option = pkcs5.padopt; + algd.Pad_Character = pkcs5.padchar; + algd.Effective_Key_Size = pkcs5.effkeysize; + memcpy(algd.Init_Vector, pkcs5.iv, pkcs5.ivlen); + + /* Create the key and algorithm context tokens. */ + *ctx = libssh2_init_crypto_ctx(NULL); + if (!*ctx) { + LIBSSH2_FREE(session, dk); + return -1; + } + libssh2_init_crypto_ctx(*ctx); + set_EC_length(errcode, sizeof errcode); + Qc3CreateKeyContext(dk, &pkcs5.dklen, binstring, &algd.Block_Cipher_Alg, + qc3clear, NULL, NULL, (*ctx)->key.Key_Context_Token, + (char *) &errcode); + LIBSSH2_FREE(session, dk); + if (errcode.Bytes_Available) { + free((char *) *ctx); + *ctx = NULL; + return -1; + } + + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Block_Cipher, + (*ctx)->hash.Alg_Context_Token, &errcode); + if (errcode.Bytes_Available) { + Qc3DestroyKeyContext((*ctx)->key.Key_Context_Token, (char *) &ecnull); + free((char *) *ctx); + *ctx = NULL; + return -1; + } + return 1; /* Tell it's encrypted. */ +} + +static int +rsapkcs8privkey(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata) +{ + libssh2_rsa_ctx *ctx = (libssh2_rsa_ctx *) loadkeydata; + char keyform = Qc3_Clear; + char *kek = NULL; + char *kea = NULL; + _libssh2_os400qc3_crypto_ctx *kekctx; + asn1Element pki; + int pkilen; + Qus_EC_t errcode; + + switch (pkcs8kek(session, &kekctx, data, datalen, passphrase, &pki)) { + case 1: + keyform = Qc3_Encrypted; + kek = kekctx->key.Key_Context_Token; + kea = kekctx->hash.Alg_Context_Token; + case 0: + break; + default: + return -1; + } + + set_EC_length(errcode, sizeof errcode); + pkilen = pki.end - pki.beg; + Qc3CreateKeyContext((unsigned char *) pki.beg, &pkilen, berstring, + rsaprivate, &keyform, kek, kea, + ctx->key.Key_Context_Token, (char *) &errcode); + if (errcode.Bytes_Available) { + if (kekctx) + _libssh2_os400qc3_crypto_dtor(kekctx); + return -1; + } + ctx->kek = kekctx; + return 0; +} + +static char * +storewithlength(char *p, const char *data, int length) +{ + _libssh2_htonu32(p, length); + if (length) + memcpy(p + 4, data, length); + return p + 4 + length; +} + +static int +sshrsapubkey(LIBSSH2_SESSION *session, char **sshpubkey, + asn1Element *params, asn1Element *key, const char *method) +{ + int methlen = strlen(method); + asn1Element keyseq; + asn1Element m; + asn1Element e; + int len; + char *cp; + + if (getASN1Element(&keyseq, key->beg + 1, key->end) != key->end || + *keyseq.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if (!getASN1Element(&m, keyseq.beg, keyseq.end) || + *m.header != ASN1_INTEGER) + return -1; + if (getASN1Element(&e, m.end, keyseq.end) != keyseq.end || + *e.header != ASN1_INTEGER) + return -1; + len = 4 + methlen + 4 + (e.end - e.beg) + 4 + (m.end - m.beg); + cp = LIBSSH2_ALLOC(session, len); + if (!cp) + return -1; + *sshpubkey = cp; + cp = storewithlength(cp, method, methlen); + cp = storewithlength(cp, e.beg, e.end - e.beg); + cp = storewithlength(cp, m.beg, m.end - m.beg); + return len; +} + +static int +rsapkcs8pubkey(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata) +{ + loadpubkeydata *p = (loadpubkeydata *) loadkeydata; + char *buf; + int len; + char *cp; + int i; + char keyform = Qc3_Clear; + char *kek = NULL; + char *kea = NULL; + _libssh2_os400qc3_crypto_ctx *kekctx; + asn1Element subjpubkeyinfo; + asn1Element algorithmid; + asn1Element algorithm; + asn1Element subjpubkey; + asn1Element parameters; + asn1Element pki; + int pkilen; + Qus_EC_t errcode; + + if (!(buf = alloca(datalen))) + return -1; + + switch (pkcs8kek(session, &kekctx, data, datalen, passphrase, &pki)) { + case 1: + keyform = Qc3_Encrypted; + kek = kekctx->key.Key_Context_Token; + kea = kekctx->hash.Alg_Context_Token; + case 0: + break; + default: + return -1; + } + + set_EC_length(errcode, sizeof errcode); + pkilen = pki.end - pki.beg; + Qc3ExtractPublicKey(pki.beg, &pkilen, berstring, &keyform, + kek, kea, buf, (int *) &datalen, &len, &errcode); + _libssh2_os400qc3_crypto_dtor(kekctx); + if (errcode.Bytes_Available) + return -1; + /* Get the algorithm OID and key data from SubjectPublicKeyInfo. */ + if (getASN1Element(&subjpubkeyinfo, buf, buf + len) != buf + len || + *subjpubkeyinfo.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&algorithmid, subjpubkeyinfo.beg, subjpubkeyinfo.end); + if (!cp || *algorithmid.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if (!getASN1Element(&algorithm, algorithmid.beg, algorithmid.end) || + *algorithm.header != ASN1_OBJ_ID) + return -1; + if (getASN1Element(&subjpubkey, cp, subjpubkeyinfo.end) != + subjpubkeyinfo.end || *subjpubkey.header != ASN1_BIT_STRING) + return -1; + /* Check for supported algorithm. */ + for (i = 0; pka[i].oid; i++) + if (!oidcmp(&algorithm, pka[i].oid)) { + len = (*pka[i].sshpubkey)(session, &p->data, &algorithmid, + &subjpubkey, pka[i].method); + if (len < 0) + return -1; + p->length = len; + p->method = pka[i].method; + return 0; + } + return -1; /* Algorithm not supported. */ +} + +static int +pkcs1topkcs8(LIBSSH2_SESSION *session, + const unsigned char **data8, unsigned int *datalen8, + const unsigned char *data1, unsigned int datalen1) +{ + asn1Element *prvk; + asn1Element *pkcs8; + unsigned char *data; + + *data8 = NULL; + *datalen8 = 0; + if (datalen1 < 2) + return -1; + prvk = asn1_new_from_bytes(data1, datalen1); + if (!prvk) + return -1; + pkcs8 = rsaprivatekeyinfo(prvk); + asn1delete(prvk); + if (!prvk) { + asn1delete(pkcs8); + pkcs8 = NULL; + } + if (!pkcs8) + return -1; + data = (unsigned char *) LIBSSH2_ALLOC(session, pkcs8->end - pkcs8->header); + if (!data) { + asn1delete(pkcs8); + return -1; + } + *data8 = data; + *datalen8 = pkcs8->end - pkcs8->header; + memcpy((char *) data, (char *) pkcs8->header, *datalen8); + asn1delete(pkcs8); + return 0; +} + +static int +rsapkcs1privkey(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata) +{ + const unsigned char *data8; + unsigned int datalen8; + int ret; + + if (pkcs1topkcs8(session, &data8, &datalen8, data, datalen)) + return -1; + ret = rsapkcs8privkey(session, data8, datalen8, passphrase, loadkeydata); + LIBSSH2_FREE(session, (char *) data8); + return ret; +} + +static int +rsapkcs1pubkey(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata) +{ + const unsigned char *data8; + unsigned int datalen8; + int ret; + + if (pkcs1topkcs8(session, &data8, &datalen8, data, datalen)) + return -1; + ret = rsapkcs8pubkey(session, data8, datalen8, passphrase, loadkeydata); + LIBSSH2_FREE(session, (char *) data8); + return ret; +} + +static int +try_pem_load(LIBSSH2_SESSION *session, FILE *fp, + const unsigned char *passphrase, + const char *header, const char *trailer, + loadkeyproc proc, void *loadkeydata) +{ + unsigned char *data = NULL; + unsigned int datalen = 0; + int c; + int ret; + + fseek(fp, 0L, SEEK_SET); + for (;;) { + ret = _libssh2_pem_parse(session, header, trailer, + fp, &data, &datalen); + + if (!ret) { + ret = (*proc)(session, data, datalen, passphrase, loadkeydata); + if (!ret) + return 0; + } + + if (data) { + LIBSSH2_FREE(session, data); + data = NULL; + } + c = getc(fp); + + if (c == EOF) + break; + + ungetc(c, fp); + } + + return -1; +} + +static int +load_rsa_private_file(LIBSSH2_SESSION *session, const char *filename, + unsigned const char *passphrase, + loadkeyproc proc1, loadkeyproc proc8, void *loadkeydata) +{ + FILE *fp = fopen(filename, fopenrmode); + unsigned char *data = NULL; + size_t datalen = 0; + int ret; + long filesize; + + if (!fp) + return -1; + + /* Try with "ENCRYPTED PRIVATE KEY" PEM armor. + --> PKCS#8 EncryptedPrivateKeyInfo */ + ret = try_pem_load(session, fp, passphrase, beginencprivkeyhdr, + endencprivkeyhdr, proc8, loadkeydata); + + /* Try with "PRIVATE KEY" PEM armor. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + if (ret) + ret = try_pem_load(session, fp, passphrase, beginprivkeyhdr, + endprivkeyhdr, proc8, loadkeydata); + + /* Try with "RSA PRIVATE KEY" PEM armor. + --> PKCS#1 RSAPrivateKey */ + if (ret) + ret = try_pem_load(session, fp, passphrase, beginrsaprivkeyhdr, + endrsaprivkeyhdr, proc1, loadkeydata); + fclose(fp); + + if (ret) { + /* Try DER encoding. */ + fp = fopen(filename, fopenrbmode); + fseek(fp, 0L, SEEK_END); + filesize = ftell(fp); + + if (filesize <= 32768) { /* Limit to a reasonable size. */ + datalen = filesize; + data = (unsigned char *) alloca(datalen); + if (data) { + fseek(fp, 0L, SEEK_SET); + fread(data, datalen, 1, fp); + + /* Try as PKCS#8 DER data. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + ret = (*proc8)(session, data, datalen, passphrase, + loadkeydata); + + /* Try as PKCS#1 DER data. + --> PKCS#1 RSAPrivateKey */ + if (ret) + ret = (*proc1)(session, data, datalen, passphrase, + loadkeydata); + } + } + fclose(fp); + } + + return ret; +} + +int +_libssh2_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, + const char *filename, unsigned const char *passphrase) +{ + libssh2_rsa_ctx *ctx = libssh2_init_crypto_ctx(NULL); + int ret; + Qc3_Format_ALGD0400_T algd; + Qus_EC_t errcode; + + if (!ctx) + return -1; + ret = load_rsa_private_file(session, filename, passphrase, + rsapkcs1privkey, rsapkcs8privkey, (void *) ctx); + if (!ret) { + /* Create the algorithm context. */ + algd.Public_Key_Alg = Qc3_RSA; + algd.PKA_Block_Format = Qc3_PKCS1_01; + memset(algd.Reserved, 0, sizeof algd.Reserved); + algd.Signing_Hash_Alg = Qc3_SHA1; + set_EC_length(errcode, sizeof errcode); + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Public_Key, + ctx->hash.Alg_Context_Token, &errcode); + if (errcode.Bytes_Available) + ret = -1; + } + if (ret) { + _libssh2_os400qc3_crypto_dtor(ctx); + ctx = NULL; + } + *rsa = ctx; + return ret; +} + +int +_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, size_t *method_len, + unsigned char **pubkeydata, size_t *pubkeydata_len, + const char *privatekey, const char *passphrase) + +{ + loadpubkeydata p; + int ret; + + *method = NULL; + *method_len = 0; + *pubkeydata = NULL; + *pubkeydata_len = 0; + + ret = load_rsa_private_file(session, privatekey, passphrase, + rsapkcs1pubkey, rsapkcs8pubkey, (void *) &p); + if (!ret) { + *method_len = strlen(p.method); + if ((*method = LIBSSH2_ALLOC(session, *method_len))) + memcpy((char *) *method, p.method, *method_len); + else + ret = -1; + } + + if (ret) { + if (*method) + LIBSSH2_FREE(session, *method); + if (p.data) + LIBSSH2_FREE(session, (void *) p.data); + *method = NULL; + *method_len = 0; + } else { + *pubkeydata = (unsigned char *) p.data; + *pubkeydata_len = p.length; + } + + return ret; +} + +int +_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ + libssh2_rsa_ctx *ctx = libssh2_init_crypto_ctx(NULL); + unsigned char *data = NULL; + unsigned int datalen = 0; + int ret; + Qc3_Format_ALGD0400_T algd; + Qus_EC_t errcode; + + if (!ctx) + return -1; + + /* Try with "ENCRYPTED PRIVATE KEY" PEM armor. + --> PKCS#8 EncryptedPrivateKeyInfo */ + ret = _libssh2_pem_parse_memory(session, + beginencprivkeyhdr, endencprivkeyhdr, + filedata, filedata_len, &data, &datalen); + + /* Try with "PRIVATE KEY" PEM armor. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + if (ret) + ret = _libssh2_pem_parse_memory(session, + beginprivkeyhdr, endprivkeyhdr, + filedata, filedata_len, + &data, &datalen); + + if (!ret) { + /* Process PKCS#8. */ + ret = rsapkcs8privkey(session, + data, datalen, passphrase, (void *) &ctx); + } else { + /* Try with "RSA PRIVATE KEY" PEM armor. + --> PKCS#1 RSAPrivateKey */ + ret = _libssh2_pem_parse_memory(session, + beginrsaprivkeyhdr, endrsaprivkeyhdr, + filedata, filedata_len, + &data, &datalen); + if (!ret) + ret = rsapkcs1privkey(session, + data, datalen, passphrase, (void *) &ctx); + } + + if (ret) { + /* Try as PKCS#8 DER data. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + ret = rsapkcs8privkey(session, filedata, filedata_len, + passphrase, (void *) &ctx); + + /* Try as PKCS#1 DER data. + --> PKCS#1 RSAPrivateKey */ + if (ret) + ret = rsapkcs1privkey(session, filedata, filedata_len, + passphrase, (void *) &ctx); + } + + if (data) + LIBSSH2_FREE(session, data); + + if (!ret) { + /* Create the algorithm context. */ + algd.Public_Key_Alg = Qc3_RSA; + algd.PKA_Block_Format = Qc3_PKCS1_01; + memset(algd.Reserved, 0, sizeof algd.Reserved); + algd.Signing_Hash_Alg = Qc3_SHA1; + set_EC_length(errcode, sizeof errcode); + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Public_Key, + ctx->hash.Alg_Context_Token, &errcode); + if (errcode.Bytes_Available) + ret = -1; + } + + if (ret) { + _libssh2_os400qc3_crypto_dtor(ctx); + ctx = NULL; + } + + *rsa = ctx; + return ret; +} + +int +_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + loadpubkeydata p; + unsigned char *data = NULL; + unsigned int datalen = 0; + const char *meth; + int ret; + + *method = NULL; + *method_len = 0; + *pubkeydata = NULL; + *pubkeydata_len = 0; + + /* Try with "ENCRYPTED PRIVATE KEY" PEM armor. + --> PKCS#8 EncryptedPrivateKeyInfo */ + ret = _libssh2_pem_parse_memory(session, + beginencprivkeyhdr, endencprivkeyhdr, + privatekeydata, privatekeydata_len, + &data, &datalen); + + /* Try with "PRIVATE KEY" PEM armor. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + if (ret) + ret = _libssh2_pem_parse_memory(session, + beginprivkeyhdr, endprivkeyhdr, + privatekeydata, privatekeydata_len, + &data, &datalen); + + if (!ret) { + /* Process PKCS#8. */ + ret = rsapkcs8pubkey(session, + data, datalen, passphrase, (void *) &p); + } else { + /* Try with "RSA PRIVATE KEY" PEM armor. + --> PKCS#1 RSAPrivateKey */ + ret = _libssh2_pem_parse_memory(session, + beginrsaprivkeyhdr, endrsaprivkeyhdr, + privatekeydata, privatekeydata_len, + &data, &datalen); + if (!ret) + ret = rsapkcs1pubkey(session, + data, datalen, passphrase, (void *) &p); + } + + if (ret) { + /* Try as PKCS#8 DER data. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + ret = rsapkcs8pubkey(session, privatekeydata, privatekeydata_len, + passphrase, (void *) &p); + + /* Try as PKCS#1 DER data. + --> PKCS#1 RSAPrivateKey */ + if (ret) + ret = rsapkcs1pubkey(session, privatekeydata, privatekeydata_len, + passphrase, (void *) &p); + } + + if (data) + LIBSSH2_FREE(session, data); + + if (!ret) { + *method_len = strlen(p.method); + if ((*method = LIBSSH2_ALLOC(session, *method_len))) + memcpy((char *) *method, p.method, *method_len); + else + ret = -1; + } + if (ret) { + if (*method) + LIBSSH2_FREE(session, *method); + if (p.data) + LIBSSH2_FREE(session, (void *) p.data); + *method = NULL; + *method_len = 0; + } else { + *pubkeydata = (unsigned char *) p.data; + *pubkeydata_len = p.length; + } + + return ret; +} + +int +_libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, unsigned long sig_len, + const unsigned char *m, unsigned long m_len) +{ + Qus_EC_t errcode; + int slen = sig_len; + int mlen = m_len; + + set_EC_length(errcode, sizeof errcode); + Qc3VerifySignature((char *) sig, &slen, (char *) m, &mlen, Qc3_Data, + rsa->hash.Alg_Context_Token, Qc3_Alg_Token, + rsa->key.Key_Context_Token, Qc3_Key_Token, anycsp, + NULL, (char *) &errcode); + return errcode.Bytes_Available? -1: 0; +} + +int +_libssh2_os400qc3_rsa_sha1_signv(LIBSSH2_SESSION *session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec vector[], + libssh2_rsa_ctx *ctx) +{ + Qus_EC_t errcode; + int siglen; + unsigned char *sig; + char sigbuf[8192]; + int sigbufsize = sizeof sigbuf; + + ctx->hash.Final_Op_Flag = Qc3_Final; + set_EC_length(errcode, sizeof errcode); + Qc3CalculateSignature((char *) vector, &veccount, Qc3_Array, + (char *) &ctx->hash, Qc3_Alg_Token, + (char *) &ctx->key, Qc3_Key_Token, + anycsp, NULL, sigbuf, &sigbufsize, &siglen, + (char *) &errcode); + ctx->hash.Final_Op_Flag = Qc3_Continue; + if (errcode.Bytes_Available) + return -1; + sig = LIBSSH2_ALLOC(session, siglen); + if (!sig) + return -1; + memcpy((char *) sig, sigbuf, siglen); + *signature = sig; + *signature_len = siglen; + return 0; +} + +void +_libssh2_init_aes_ctr(void) +{ +} + +#endif /* LIBSSH2_OS400QC3 */ + +/* vim: set expandtab ts=4 sw=4: */ diff --git a/libssh2/src/os400qc3.h b/libssh2/src/os400qc3.h new file mode 100644 index 000000000..dbaa581f6 --- /dev/null +++ b/libssh2/src/os400qc3.h @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2015 Patrick Monnerat, D+H + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef LIBSSH2_OS400QC3_H +#define LIBSSH2_OS400QC3_H + +#include +#include + +#include + + +/* Redefine character/string literals as always EBCDIC. */ +#undef Qc3_Alg_Token +#define Qc3_Alg_Token "\xC1\xD3\xC7\xC4\xF0\xF1\xF0\xF0" /* ALGD0100 */ +#undef Qc3_Alg_Block_Cipher +#define Qc3_Alg_Block_Cipher "\xC1\xD3\xC7\xC4\xF0\xF2\xF0\xF0" /* ALGD0200 */ +#undef Qc3_Alg_Block_CipherAuth +#define Qc3_Alg_Block_CipherAuth \ + "\xC1\xD3\xC7\xC4\xF0\xF2\xF1\xF0" /* ALGD0210 */ +#undef Qc3_Alg_Stream_Cipher +#define Qc3_Alg_Stream_Cipher \ + "\xC1\xD3\xC7\xC4\xF0\xF3\xF0\xF0" /* ALGD0300 */ +#undef Qc3_Alg_Public_Key +#define Qc3_Alg_Public_Key "\xC1\xD3\xC7\xC4\xF0\xF4\xF0\xF0" /* ALGD0400 */ +#undef Qc3_Alg_Hash +#define Qc3_Alg_Hash "\xC1\xD3\xC7\xC4\xF0\xF5\xF0\xF0" /* ALGD0500 */ +#undef Qc3_Data +#define Qc3_Data "\xC4\xC1\xE3\xC1\xF0\xF1\xF0\xF0" /* DATA0100 */ +#undef Qc3_Array +#define Qc3_Array "\xC4\xC1\xE3\xC1\xF0\xF2\xF0\xF0" /* DATA0200 */ +#undef Qc3_Key_Token +#define Qc3_Key_Token "\xD2\xC5\xE8\xC4\xF0\xF1\xF0\xF0" /* KEYD0100 */ +#undef Qc3_Key_Parms +#define Qc3_Key_Parms "\xD2\xC5\xE8\xC4\xF0\xF2\xF0\xF0" /* KEYD0200 */ +#undef Qc3_Key_KSLabel +#define Qc3_Key_KSLabel "\xD2\xC5\xE8\xC4\xF0\xF4\xF0\xF0" /* KEYD0400 */ +#undef Qc3_Key_PKCS5 +#define Qc3_Key_PKCS5 "\xD2\xC5\xE8\xC4\xF0\xF5\xF0\xF0" /* KEYD0500 */ +#undef Qc3_Key_PEMCert +#define Qc3_Key_PEMCert "\xD2\xC5\xE8\xC4\xF0\xF6\xF0\xF0" /* KEYD0600 */ +#undef Qc3_Key_CSLabel +#define Qc3_Key_CSLabel "\xD2\xC5\xE8\xC4\xF0\xF7\xF0\xF0" /* KEYD0700 */ +#undef Qc3_Key_CSDN +#define Qc3_Key_CSDN "\xD2\xC5\xE8\xC4\xF0\xF8\xF0\xF0" /* KEYD0800 */ +#undef Qc3_Key_AppID +#define Qc3_Key_AppID "\xD2\xC5\xE8\xC4\xF0\xF9\xF0\xF0" /* KEYD0900 */ + +#undef Qc3_ECB +#define Qc3_ECB '\xF0' /* '0' */ +#undef Qc3_CBC +#define Qc3_CBC '\xF1' /* '1' */ +#undef Qc3_OFB +#define Qc3_OFB '\xF2' /* '2' */ +#undef Qc3_CFB1Bit +#define Qc3_CFB1Bit '\xF3' /* '3' */ +#undef Qc3_CFB8Bit +#define Qc3_CFB8Bit '\xF4' /* '4' */ +#undef Qc3_CFB64Bit +#define Qc3_CFB64Bit '\xF5' /* '5' */ +#undef Qc3_CUSP +#define Qc3_CUSP '\xF6' /* '6' */ +#undef Qc3_CTR +#define Qc3_CTR '\xF7' /* '7' */ +#undef Qc3_CCM +#define Qc3_CCM '\xF8' /* '8' */ +#undef Qc3_No_Pad +#define Qc3_No_Pad '\xF0' /* '0' */ +#undef Qc3_Pad_Char +#define Qc3_Pad_Char '\xF1' /* '1' */ +#undef Qc3_Pad_Counter +#define Qc3_Pad_Counter '\xF2' /* '2' */ +#undef Qc3_PKCS1_00 +#define Qc3_PKCS1_00 '\xF0' /* '0' */ +#undef Qc3_PKCS1_01 +#define Qc3_PKCS1_01 '\xF1' /* '1' */ +#undef Qc3_PKCS1_02 +#define Qc3_PKCS1_02 '\xF2' /* '2' */ +#undef Qc3_ISO9796 +#define Qc3_ISO9796 '\xF3' /* '3' */ +#undef Qc3_Zero_Pad +#define Qc3_Zero_Pad '\xF4' /* '4' */ +#undef Qc3_ANSI_X931 +#define Qc3_ANSI_X931 '\xF5' /* '5' */ +#undef Qc3_OAEP +#define Qc3_OAEP '\xF6' /* '6' */ +#undef Qc3_Bin_String +#define Qc3_Bin_String '\xF0' /* '0' */ +#undef Qc3_BER_String +#define Qc3_BER_String '\xF1' /* '1' */ +#undef Qc3_MK_Struct +#define Qc3_MK_Struct '\xF3' /* '3' */ +#undef Qc3_KSLabel_Struct +#define Qc3_KSLabel_Struct '\xF4' /* '4' */ +#undef Qc3_PKCS5_Struct +#define Qc3_PKCS5_Struct '\xF5' /* '5' */ +#undef Qc3_PEMCert_String +#define Qc3_PEMCert_String '\xF6' /* '6' */ +#undef Qc3_CSLabel_String +#define Qc3_CSLabel_String '\xF7' /* '7' */ +#undef Qc3_CSDN_String +#define Qc3_CSDN_String '\xF8' /* '8' */ +#undef Qc3_Clear +#define Qc3_Clear '\xF0' /* '0' */ +#undef Qc3_Encrypted +#define Qc3_Encrypted '\xF1' /* '1' */ +#undef Qc3_MK_Encrypted +#define Qc3_MK_Encrypted '\xF2' /* '2' */ +#undef Qc3_Any_CSP +#define Qc3_Any_CSP '\xF0' /* '0' */ +#undef Qc3_Sfw_CSP +#define Qc3_Sfw_CSP '\xF1' /* '1' */ +#undef Qc3_Hdw_CSP +#define Qc3_Hdw_CSP '\xF2' /* '2' */ +#undef Qc3_Continue +#define Qc3_Continue '\xF0' /* '0' */ +#undef Qc3_Final +#define Qc3_Final '\xF1' /* '1' */ +#undef Qc3_MK_New +#define Qc3_MK_New '\xF0' /* '0' */ +#undef Qc3_MK_Current +#define Qc3_MK_Current '\xF1' /* '1' */ +#undef Qc3_MK_Old +#define Qc3_MK_Old '\xF2' /* '2' */ +#undef Qc3_MK_Pending +#define Qc3_MK_Pending '\xF3' /* '3' */ + + +/* Define which features are supported. */ +#define LIBSSH2_MD5 1 +#define LIBSSH2_HMAC_RIPEMD 0 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#define LIBSSH2_AES 1 +#define LIBSSH2_AES_CTR 1 +#define LIBSSH2_BLOWFISH 0 +#define LIBSSH2_RC4 1 +#define LIBSSH2_CAST 0 +#define LIBSSH2_3DES 1 + +#define LIBSSH2_RSA 1 +#define LIBSSH2_DSA 0 + +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 +#define SHA512_DIGEST_LENGTH 64 + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: global handles structures. + * + *******************************************************************/ + +/* HMAC & private key algorithms support structure. */ +typedef struct _libssh2_os400qc3_crypto_ctx _libssh2_os400qc3_crypto_ctx; +struct _libssh2_os400qc3_crypto_ctx { + Qc3_Format_ALGD0100_T hash; /* Hash algorithm. */ + Qc3_Format_KEYD0100_T key; /* Key. */ + _libssh2_os400qc3_crypto_ctx * kek; /* Key encryption. */ +}; + +typedef struct { /* Big number. */ + unsigned char * bignum; /* Number bits, little-endian. */ + unsigned int length; /* Length of bignum (# bytes). */ +} _libssh2_bn; + +typedef struct { /* Algorithm description. */ + char * fmt; /* Format of Qc3 structure. */ + int algo; /* Algorithm identifier. */ + unsigned char size; /* Block length. */ + unsigned char mode; /* Block mode. */ + int keylen; /* Key length. */ +} _libssh2_os400qc3_cipher_t; + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: Define global types/codes. + * + *******************************************************************/ + +#define libssh2_crypto_init() +#define libssh2_crypto_exit() + +#define libssh2_sha1_ctx Qc3_Format_ALGD0100_T +#define libssh2_sha256_ctx Qc3_Format_ALGD0100_T +#define libssh2_md5_ctx Qc3_Format_ALGD0100_T +#define libssh2_hmac_ctx _libssh2_os400qc3_crypto_ctx +#define _libssh2_cipher_ctx _libssh2_os400qc3_crypto_ctx + +#define libssh2_sha1_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA1) +#define libssh2_sha1_update(ctx, data, len) \ + libssh2_os400qc3_hash_update(&(ctx), data, len) +#define libssh2_sha1_final(ctx, out) \ + libssh2_os400qc3_hash_final(&(ctx), out) +#define libssh2_sha256_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA256) +#define libssh2_sha256_update(ctx, data, len) \ + libssh2_os400qc3_hash_update(&(ctx), data, len) +#define libssh2_sha256_final(ctx, out) \ + libssh2_os400qc3_hash_final(&(ctx), out) +#define libssh2_sha256(message, len, out) \ + libssh2_os400qc3_hash(message, len, out, \ + Qc3_SHA256) +#define libssh2_md5_init(x) libssh2_os400qc3_hash_init(x, Qc3_MD5) +#define libssh2_md5_update(ctx, data, len) \ + libssh2_os400qc3_hash_update(&(ctx), data, len) +#define libssh2_md5_final(ctx, out) \ + libssh2_os400qc3_hash_final(&(ctx), out) +#define libssh2_hmac_ctx_init(ctx) \ + memset((char *) &(ctx), 0, \ + sizeof(libssh2_hmac_ctx)) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + libssh2_os400qc3_hmac_init(ctx, Qc3_MD5, \ + MD5_DIGEST_LENGTH, \ + key, keylen) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + libssh2_os400qc3_hmac_init(ctx, Qc3_SHA1, \ + SHA_DIGEST_LENGTH, \ + key, keylen) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + libssh2_os400qc3_hmac_init(ctx, Qc3_SHA256, \ + SHA256_DIGEST_LENGTH, \ + key, keylen) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + libssh2_os400qc3_hmac_init(ctx, Qc3_SHA512, \ + SHA512_DIGEST_LENGTH, \ + key, keylen) +#define libssh2_hmac_update(ctx, data, datalen) \ + libssh2_os400qc3_hmac_update(&(ctx), \ + data, datalen) +#define libssh2_hmac_final(ctx, data) \ + libssh2_os400qc3_hmac_final(&(ctx), data) +#define libssh2_hmac_cleanup(ctx) \ + _libssh2_os400qc3_crypto_dtor(ctx) + + +#define _libssh2_bn_ctx int /* Not used. */ + +#define _libssh2_bn_ctx_new() 0 +#define _libssh2_bn_ctx_free(bnctx) ((void) 0) + +#define _libssh2_bn_init_from_bin() _libssh2_bn_init() +#define _libssh2_bn_mod_exp(r, a, p, m, ctx) \ + _libssh2_os400qc3_bn_mod_exp(r, a, p, m) +#define _libssh2_bn_bytes(bn) ((bn)->length) + +#define _libssh2_cipher_type(name) _libssh2_os400qc3_cipher_t name +#define _libssh2_cipher_aes128 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ + Qc3_CBC, 16} +#define _libssh2_cipher_aes192 {Qc3_Alg_Block_Cipher, Qc3_AES, 24, \ + Qc3_CBC, 24} +#define _libssh2_cipher_aes256 {Qc3_Alg_Block_Cipher, Qc3_AES, 32, \ + Qc3_CBC, 32} +#define _libssh2_cipher_aes128ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ + Qc3_CTR, 16} +#define _libssh2_cipher_aes192ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 24, \ + Qc3_CTR, 24} +#define _libssh2_cipher_aes256ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 32, \ + Qc3_CTR, 32} +#define _libssh2_cipher_3des {Qc3_Alg_Block_Cipher, Qc3_TDES, 0, \ + Qc3_CBC, 24} +#define _libssh2_cipher_arcfour {Qc3_Alg_Stream_Cipher, Qc3_RC4, 0, 0, 16} + +#define _libssh2_cipher_dtor(ctx) _libssh2_os400qc3_crypto_dtor(ctx) + +#define libssh2_rsa_ctx _libssh2_os400qc3_crypto_ctx +#define _libssh2_rsa_free(ctx) (_libssh2_os400qc3_crypto_dtor(ctx), \ + free((char *) ctx)) +#define libssh2_prepare_iovec(vec, len) memset((char *) (vec), 0, \ + (len) * sizeof(struct iovec)) +#define _libssh2_rsa_sha1_signv(session, sig, siglen, count, vector, ctx) \ + _libssh2_os400qc3_rsa_sha1_signv(session, sig, siglen, \ + count, vector, ctx) + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: Support procedure prototypes. + * + *******************************************************************/ + +extern _libssh2_bn * _libssh2_bn_init(void); +extern void _libssh2_bn_free(_libssh2_bn *bn); +extern unsigned long _libssh2_bn_bits(_libssh2_bn *bn); +extern int _libssh2_bn_from_bin(_libssh2_bn *bn, int len, + const unsigned char *v); +extern int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val); +extern int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val); +extern void _libssh2_random(unsigned char *buf, int len); +extern int _libssh2_bn_rand(_libssh2_bn *bn, int bits, + int top, int bottom); +extern int _libssh2_os400qc3_bn_mod_exp(_libssh2_bn *r, _libssh2_bn *a, + _libssh2_bn *p, _libssh2_bn *m); +extern void _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x); +extern int libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, + unsigned int algo); +extern void libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, + unsigned char *data, int len); +extern void libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, + unsigned char *out); +extern int libssh2_os400qc3_hash(const unsigned char *message, + unsigned long len, unsigned char *out, + unsigned int algo); +extern void libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *x, + int algo, size_t minkeylen, + void *key, int keylen); +extern void libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx, + const unsigned char *data, + int len); +extern void libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx, + unsigned char *out); +extern int _libssh2_os400qc3_rsa_sha1_signv(LIBSSH2_SESSION *session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec vector[], + libssh2_rsa_ctx *ctx); + +#endif + +/* vim: set expandtab ts=4 sw=4: */ diff --git a/libssh2/src/packet.c b/libssh2/src/packet.c new file mode 100644 index 000000000..5f1feb8c6 --- /dev/null +++ b/libssh2/src/packet.c @@ -0,0 +1,1267 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2005,2006 Mikhail Gusarov + * Copyright (c) 2009-2014 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#endif + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#include + +#include "transport.h" +#include "channel.h" +#include "packet.h" + +/* + * libssh2_packet_queue_listener + * + * Queue a connection request for a listener + */ +static inline int +packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long datalen, + packet_queue_listener_state_t *listen_state) +{ + /* + * Look for a matching listener + */ + /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ + unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1); + unsigned char *p; + LIBSSH2_LISTENER *listn = _libssh2_list_first(&session->listeners); + char failure_code = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; + int rc; + + (void) datalen; + + if (listen_state->state == libssh2_NB_state_idle) { + unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5; + listen_state->sender_channel = _libssh2_ntohu32(s); + s += 4; + + listen_state->initial_window_size = _libssh2_ntohu32(s); + s += 4; + listen_state->packet_size = _libssh2_ntohu32(s); + s += 4; + + listen_state->host_len = _libssh2_ntohu32(s); + s += 4; + listen_state->host = s; + s += listen_state->host_len; + listen_state->port = _libssh2_ntohu32(s); + s += 4; + + listen_state->shost_len = _libssh2_ntohu32(s); + s += 4; + listen_state->shost = s; + s += listen_state->shost_len; + listen_state->sport = _libssh2_ntohu32(s); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Remote received connection from %s:%ld to %s:%ld", + listen_state->shost, listen_state->sport, + listen_state->host, listen_state->port); + + listen_state->state = libssh2_NB_state_allocated; + } + + if (listen_state->state != libssh2_NB_state_sent) { + while (listn) { + if ((listn->port == (int) listen_state->port) && + (strlen(listn->host) == listen_state->host_len) && + (memcmp (listn->host, listen_state->host, + listen_state->host_len) == 0)) { + /* This is our listener */ + LIBSSH2_CHANNEL *channel = NULL; + listen_state->channel = NULL; + + if (listen_state->state == libssh2_NB_state_allocated) { + if (listn->queue_maxsize && + (listn->queue_maxsize <= listn->queue_size)) { + /* Queue is full */ + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Listener queue full, ignoring"); + listen_state->state = libssh2_NB_state_sent; + break; + } + + channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if (!channel) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a channel for " + "new connection"); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + listen_state->state = libssh2_NB_state_sent; + break; + } + listen_state->channel = channel; + + channel->session = session; + channel->channel_type_len = sizeof("forwarded-tcpip") - 1; + channel->channel_type = LIBSSH2_ALLOC(session, + channel-> + channel_type_len + + 1); + if (!channel->channel_type) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a channel for new" + " connection"); + LIBSSH2_FREE(session, channel); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + listen_state->state = libssh2_NB_state_sent; + break; + } + memcpy(channel->channel_type, "forwarded-tcpip", + channel->channel_type_len + 1); + + channel->remote.id = listen_state->sender_channel; + channel->remote.window_size_initial = + LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.window_size = + LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.packet_size = + LIBSSH2_CHANNEL_PACKET_DEFAULT; + + channel->local.id = _libssh2_channel_nextid(session); + channel->local.window_size_initial = + listen_state->initial_window_size; + channel->local.window_size = + listen_state->initial_window_size; + channel->local.packet_size = listen_state->packet_size; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Connection queued: channel %lu/%lu " + "win %lu/%lu packet %lu/%lu", + channel->local.id, channel->remote.id, + channel->local.window_size, + channel->remote.window_size, + channel->local.packet_size, + channel->remote.packet_size); + + p = listen_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; + _libssh2_store_u32(&p, channel->remote.id); + _libssh2_store_u32(&p, channel->local.id); + _libssh2_store_u32(&p, + channel->remote.window_size_initial); + _libssh2_store_u32(&p, channel->remote.packet_size); + + listen_state->state = libssh2_NB_state_created; + } + + if (listen_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, listen_state->packet, + 17, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (rc) { + listen_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send channel " + "open confirmation"); + } + + /* Link the channel into the end of the queue list */ + if (listen_state->channel) { + _libssh2_list_add(&listn->queue, + &listen_state->channel->node); + listn->queue_size++; + } + + listen_state->state = libssh2_NB_state_idle; + return 0; + } + } + + listn = _libssh2_list_next(&listn->node); + } + + listen_state->state = libssh2_NB_state_sent; + } + + /* We're not listening to you */ + p = listen_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; + _libssh2_store_u32(&p, listen_state->sender_channel); + _libssh2_store_u32(&p, failure_code); + _libssh2_store_str(&p, FwdNotReq, sizeof(FwdNotReq) - 1); + _libssh2_htonu32(p, 0); + + rc = _libssh2_transport_send(session, listen_state->packet, + packet_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + listen_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, "Unable to send open failure"); + + } + listen_state->state = libssh2_NB_state_idle; + return 0; +} + +/* + * packet_x11_open + * + * Accept a forwarded X11 connection + */ +static inline int +packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long datalen, + packet_x11_open_state_t *x11open_state) +{ + int failure_code = SSH_OPEN_CONNECT_FAILED; + /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ + unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1); + unsigned char *p; + LIBSSH2_CHANNEL *channel = x11open_state->channel; + int rc; + + (void) datalen; + + if (x11open_state->state == libssh2_NB_state_idle) { + unsigned char *s = data + (sizeof("x11") - 1) + 5; + x11open_state->sender_channel = _libssh2_ntohu32(s); + s += 4; + x11open_state->initial_window_size = _libssh2_ntohu32(s); + s += 4; + x11open_state->packet_size = _libssh2_ntohu32(s); + s += 4; + x11open_state->shost_len = _libssh2_ntohu32(s); + s += 4; + x11open_state->shost = s; + s += x11open_state->shost_len; + x11open_state->sport = _libssh2_ntohu32(s); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "X11 Connection Received from %s:%ld on channel %lu", + x11open_state->shost, x11open_state->sport, + x11open_state->sender_channel); + + x11open_state->state = libssh2_NB_state_allocated; + } + + if (session->x11) { + if (x11open_state->state == libssh2_NB_state_allocated) { + channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if (!channel) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "allocate a channel for new connection"); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + goto x11_exit; + } + + channel->session = session; + channel->channel_type_len = sizeof("x11") - 1; + channel->channel_type = LIBSSH2_ALLOC(session, + channel->channel_type_len + + 1); + if (!channel->channel_type) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "allocate a channel for new connection"); + LIBSSH2_FREE(session, channel); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + goto x11_exit; + } + memcpy(channel->channel_type, "x11", + channel->channel_type_len + 1); + + channel->remote.id = x11open_state->sender_channel; + channel->remote.window_size_initial = + LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; + + channel->local.id = _libssh2_channel_nextid(session); + channel->local.window_size_initial = + x11open_state->initial_window_size; + channel->local.window_size = x11open_state->initial_window_size; + channel->local.packet_size = x11open_state->packet_size; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "X11 Connection established: channel %lu/%lu " + "win %lu/%lu packet %lu/%lu", + channel->local.id, channel->remote.id, + channel->local.window_size, + channel->remote.window_size, + channel->local.packet_size, + channel->remote.packet_size); + p = x11open_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; + _libssh2_store_u32(&p, channel->remote.id); + _libssh2_store_u32(&p, channel->local.id); + _libssh2_store_u32(&p, channel->remote.window_size_initial); + _libssh2_store_u32(&p, channel->remote.packet_size); + + x11open_state->state = libssh2_NB_state_created; + } + + if (x11open_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, x11open_state->packet, 17, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + x11open_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel open " + "confirmation"); + } + + /* Link the channel into the session */ + _libssh2_list_add(&session->channels, &channel->node); + + /* + * Pass control to the callback, they may turn right around and + * free the channel, or actually use it + */ + LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost, + x11open_state->sport); + + x11open_state->state = libssh2_NB_state_idle; + return 0; + } + } + else + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + /* fall-trough */ + x11_exit: + p = x11open_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; + _libssh2_store_u32(&p, x11open_state->sender_channel); + _libssh2_store_u32(&p, failure_code); + _libssh2_store_str(&p, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1); + _libssh2_htonu32(p, 0); + + rc = _libssh2_transport_send(session, x11open_state->packet, packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + x11open_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, "Unable to send open failure"); + } + x11open_state->state = libssh2_NB_state_idle; + return 0; +} + +/* + * _libssh2_packet_add + * + * Create a new packet and attach it to the brigade. Called from the transport + * layer when it has received a packet. + * + * The input pointer 'data' is pointing to allocated data that this function + * is asked to deal with so on failure OR success, it must be freed fine. + * The only exception is when the return code is LIBSSH2_ERROR_EAGAIN. + * + * This function will always be called with 'datalen' greater than zero. + */ +int +_libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, + size_t datalen, int macstate) +{ + int rc = 0; + char *message=NULL; + char *language=NULL; + size_t message_len=0; + size_t language_len=0; + LIBSSH2_CHANNEL *channelp = NULL; + size_t data_head = 0; + unsigned char msg = data[0]; + + switch(session->packAdd_state) { + case libssh2_NB_state_idle: + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Packet type %d received, length=%d", + (int) msg, (int) datalen); + + if ((macstate == LIBSSH2_MAC_INVALID) && + (!session->macerror || + LIBSSH2_MACERROR(session, (char *) data, datalen))) { + /* Bad MAC input, but no callback set or non-zero return from the + callback */ + + LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC, + "Invalid MAC received"); + } + session->packAdd_state = libssh2_NB_state_allocated; + break; + case libssh2_NB_state_jump1: + goto libssh2_packet_add_jump_point1; + case libssh2_NB_state_jump2: + goto libssh2_packet_add_jump_point2; + case libssh2_NB_state_jump3: + goto libssh2_packet_add_jump_point3; + case libssh2_NB_state_jump4: + goto libssh2_packet_add_jump_point4; + case libssh2_NB_state_jump5: + goto libssh2_packet_add_jump_point5; + default: /* nothing to do */ + break; + } + + if (session->packAdd_state == libssh2_NB_state_allocated) { + /* A couple exceptions to the packet adding rule: */ + switch (msg) { + + /* + byte SSH_MSG_DISCONNECT + uint32 reason code + string description in ISO-10646 UTF-8 encoding [RFC3629] + string language tag [RFC3066] + */ + + case SSH_MSG_DISCONNECT: + if(datalen >= 5) { + size_t reason = _libssh2_ntohu32(data + 1); + + if(datalen >= 9) { + message_len = _libssh2_ntohu32(data + 5); + + if(message_len < datalen-13) { + /* 9 = packet_type(1) + reason(4) + message_len(4) */ + message = (char *) data + 9; + + language_len = _libssh2_ntohu32(data + 9 + message_len); + language = (char *) data + 9 + message_len + 4; + + if(language_len > (datalen-13-message_len)) { + /* bad input, clear info */ + language = message = NULL; + language_len = message_len = 0; + } + } + else + /* bad size, clear it */ + message_len=0; + } + if (session->ssh_msg_disconnect) { + LIBSSH2_DISCONNECT(session, reason, message, + message_len, language, language_len); + } + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Disconnect(%d): %s(%s)", reason, + message, language); + } + + LIBSSH2_FREE(session, data); + session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; + session->packAdd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT, + "socket disconnect"); + /* + byte SSH_MSG_IGNORE + string data + */ + + case SSH_MSG_IGNORE: + if (datalen >= 2) { + if (session->ssh_msg_ignore) { + LIBSSH2_IGNORE(session, (char *) data + 1, datalen - 1); + } + } else if (session->ssh_msg_ignore) { + LIBSSH2_IGNORE(session, "", 0); + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_DEBUG + boolean always_display + string message in ISO-10646 UTF-8 encoding [RFC3629] + string language tag [RFC3066] + */ + + case SSH_MSG_DEBUG: + if(datalen >= 2) { + int always_display= data[1]; + + if(datalen >= 6) { + message_len = _libssh2_ntohu32(data + 2); + + if(message_len <= (datalen - 10)) { + /* 6 = packet_type(1) + display(1) + message_len(4) */ + message = (char *) data + 6; + language_len = _libssh2_ntohu32(data + 6 + message_len); + + if(language_len <= (datalen - 10 - message_len)) + language = (char *) data + 10 + message_len; + } + } + + if (session->ssh_msg_debug) { + LIBSSH2_DEBUG(session, always_display, message, + message_len, language, language_len); + } + } + /* + * _libssh2_debug will actually truncate this for us so + * that it's not an inordinate about of data + */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Debug Packet: %s", message); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_GLOBAL_REQUEST + string request name in US-ASCII only + boolean want reply + .... request-specific data follows + */ + + case SSH_MSG_GLOBAL_REQUEST: + if(datalen >= 5) { + uint32_t len =0; + unsigned char want_reply=0; + len = _libssh2_ntohu32(data + 1); + if(datalen >= (6 + len)) { + want_reply = data[5 + len]; + _libssh2_debug(session, + LIBSSH2_TRACE_CONN, + "Received global request type %.*s (wr %X)", + len, data + 5, want_reply); + } + + + if (want_reply) { + static const unsigned char packet = + SSH_MSG_REQUEST_FAILURE; + libssh2_packet_add_jump_point5: + session->packAdd_state = libssh2_NB_state_jump5; + rc = _libssh2_transport_send(session, &packet, 1, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_CHANNEL_EXTENDED_DATA + uint32 recipient channel + uint32 data_type_code + string data + */ + + case SSH_MSG_CHANNEL_EXTENDED_DATA: + /* streamid(4) */ + data_head += 4; + + /* fall-through */ + + /* + byte SSH_MSG_CHANNEL_DATA + uint32 recipient channel + string data + */ + + case SSH_MSG_CHANNEL_DATA: + /* packet_type(1) + channelno(4) + datalen(4) */ + data_head += 9; + + if(datalen >= data_head) + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + + if (!channelp) { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, + "Packet received for unknown channel"); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } +#ifdef LIBSSH2DEBUG + { + uint32_t stream_id = 0; + if (msg == SSH_MSG_CHANNEL_EXTENDED_DATA) + stream_id = _libssh2_ntohu32(data + 5); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "%d bytes packet_add() for %lu/%lu/%lu", + (int) (datalen - data_head), + channelp->local.id, + channelp->remote.id, + stream_id); + } +#endif + if ((channelp->remote.extended_data_ignore_mode == + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) && + (msg == SSH_MSG_CHANNEL_EXTENDED_DATA)) { + /* Pretend we didn't receive this */ + LIBSSH2_FREE(session, data); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Ignoring extended data and refunding %d bytes", + (int) (datalen - 13)); + if (channelp->read_avail + datalen - data_head >= + channelp->remote.window_size) + datalen = channelp->remote.window_size - + channelp->read_avail + data_head; + + channelp->remote.window_size -= datalen - data_head; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "shrinking window size by %lu bytes to %lu, read_avail %lu", + datalen - data_head, + channelp->remote.window_size, + channelp->read_avail); + + session->packAdd_channelp = channelp; + + /* Adjust the window based on the block we just freed */ + libssh2_packet_add_jump_point1: + session->packAdd_state = libssh2_NB_state_jump1; + rc = _libssh2_channel_receive_window_adjust(session-> + packAdd_channelp, + datalen - 13, + 1, NULL); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + + /* + * REMEMBER! remote means remote as source of data, + * NOT remote window! + */ + if (channelp->remote.packet_size < (datalen - data_head)) { + /* + * Spec says we MAY ignore bytes sent beyond + * packet_size + */ + _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, + "Packet contains more data than we offered" + " to receive, truncating"); + datalen = channelp->remote.packet_size + data_head; + } + if (channelp->remote.window_size <= channelp->read_avail) { + /* + * Spec says we MAY ignore bytes sent beyond + * window_size + */ + _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, + "The current receive window is full," + " data ignored"); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + /* Reset EOF status */ + channelp->remote.eof = 0; + + if (channelp->read_avail + datalen - data_head > + channelp->remote.window_size) { + _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, + "Remote sent more data than current " + "window allows, truncating"); + datalen = channelp->remote.window_size - + channelp->read_avail + data_head; + } + + /* Update the read_avail counter. The window size will be + * updated once the data is actually read from the queue + * from an upper layer */ + channelp->read_avail += datalen - data_head; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "increasing read_avail by %lu bytes to %lu/%lu", + (long)(datalen - data_head), + (long)channelp->read_avail, + (long)channelp->remote.window_size); + + break; + + /* + byte SSH_MSG_CHANNEL_EOF + uint32 recipient channel + */ + + case SSH_MSG_CHANNEL_EOF: + if(datalen >= 5) + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + if (!channelp) + /* We may have freed already, just quietly ignore this... */ + ; + else { + _libssh2_debug(session, + LIBSSH2_TRACE_CONN, + "EOF received for channel %lu/%lu", + channelp->local.id, + channelp->remote.id); + channelp->remote.eof = 1; + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string request type in US-ASCII characters only + boolean want reply + .... type-specific data follows + */ + + case SSH_MSG_CHANNEL_REQUEST: + if(datalen >= 9) { + uint32_t channel = _libssh2_ntohu32(data + 1); + uint32_t len = _libssh2_ntohu32(data + 5); + unsigned char want_reply = 1; + + if(len < (datalen - 10)) + want_reply = data[9 + len]; + + _libssh2_debug(session, + LIBSSH2_TRACE_CONN, + "Channel %d received request type %.*s (wr %X)", + channel, len, data + 9, want_reply); + + if (len == sizeof("exit-status") - 1 + && !memcmp("exit-status", data + 9, + sizeof("exit-status") - 1)) { + + /* we've got "exit-status" packet. Set the session value */ + if(datalen >= 20) + channelp = + _libssh2_channel_locate(session, channel); + + if (channelp) { + channelp->exit_status = + _libssh2_ntohu32(data + 9 + sizeof("exit-status")); + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Exit status %lu received for " + "channel %lu/%lu", + channelp->exit_status, + channelp->local.id, + channelp->remote.id); + } + + } + else if (len == sizeof("exit-signal") - 1 + && !memcmp("exit-signal", data + 9, + sizeof("exit-signal") - 1)) { + /* command terminated due to signal */ + if(datalen >= 20) + channelp = _libssh2_channel_locate(session, channel); + + if (channelp) { + /* set signal name (without SIG prefix) */ + uint32_t namelen = + _libssh2_ntohu32(data + 9 + sizeof("exit-signal")); + channelp->exit_signal = + LIBSSH2_ALLOC(session, namelen + 1); + if (!channelp->exit_signal) + rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "memory for signal name"); + else { + memcpy(channelp->exit_signal, + data + 13 + sizeof("exit_signal"), namelen); + channelp->exit_signal[namelen] = '\0'; + /* TODO: save error message and language tag */ + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Exit signal %s received for " + "channel %lu/%lu", + channelp->exit_signal, + channelp->local.id, + channelp->remote.id); + } + } + } + + + if (want_reply) { + unsigned char packet[5]; + libssh2_packet_add_jump_point4: + session->packAdd_state = libssh2_NB_state_jump4; + packet[0] = SSH_MSG_CHANNEL_FAILURE; + memcpy(&packet[1], data+1, 4); + rc = _libssh2_transport_send(session, packet, 5, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return rc; + + /* + byte SSH_MSG_CHANNEL_CLOSE + uint32 recipient channel + */ + + case SSH_MSG_CHANNEL_CLOSE: + if(datalen >= 5) + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + if (!channelp) { + /* We may have freed already, just quietly ignore this... */ + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Close received for channel %lu/%lu", + channelp->local.id, + channelp->remote.id); + + channelp->remote.close = 1; + channelp->remote.eof = 1; + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_CHANNEL_OPEN + string "session" + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + */ + + case SSH_MSG_CHANNEL_OPEN: + if(datalen < 17) + ; + else if ((datalen >= (sizeof("forwarded-tcpip") + 4)) && + ((sizeof("forwarded-tcpip") - 1) == + _libssh2_ntohu32(data + 1)) + && + (memcmp(data + 5, "forwarded-tcpip", + sizeof("forwarded-tcpip") - 1) == 0)) { + + /* init the state struct */ + memset(&session->packAdd_Qlstn_state, 0, + sizeof(session->packAdd_Qlstn_state)); + + libssh2_packet_add_jump_point2: + session->packAdd_state = libssh2_NB_state_jump2; + rc = packet_queue_listener(session, data, datalen, + &session->packAdd_Qlstn_state); + } + else if ((datalen >= (sizeof("x11") + 4)) && + ((sizeof("x11") - 1) == _libssh2_ntohu32(data + 1)) && + (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) { + + /* init the state struct */ + memset(&session->packAdd_x11open_state, 0, + sizeof(session->packAdd_x11open_state)); + + libssh2_packet_add_jump_point3: + session->packAdd_state = libssh2_NB_state_jump3; + rc = packet_x11_open(session, data, datalen, + &session->packAdd_x11open_state); + } + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return rc; + + /* + byte SSH_MSG_CHANNEL_WINDOW_ADJUST + uint32 recipient channel + uint32 bytes to add + */ + case SSH_MSG_CHANNEL_WINDOW_ADJUST: + if(datalen < 9) + ; + else { + uint32_t bytestoadd = _libssh2_ntohu32(data + 5); + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + if(channelp) { + channelp->local.window_size += bytestoadd; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Window adjust for channel %lu/%lu, " + "adding %lu bytes, new window_size=%lu", + channelp->local.id, + channelp->remote.id, + bytestoadd, + channelp->local.window_size); + } + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + default: + break; + } + + session->packAdd_state = libssh2_NB_state_sent; + } + + if (session->packAdd_state == libssh2_NB_state_sent) { + LIBSSH2_PACKET *packetp = + LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); + if (!packetp) { + _libssh2_debug(session, LIBSSH2_ERROR_ALLOC, + "memory for packet"); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return LIBSSH2_ERROR_ALLOC; + } + packetp->data = data; + packetp->data_len = datalen; + packetp->data_head = data_head; + + _libssh2_list_add(&session->packets, &packetp->node); + + session->packAdd_state = libssh2_NB_state_sent1; + } + + if ((msg == SSH_MSG_KEXINIT && + !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) || + (session->packAdd_state == libssh2_NB_state_sent2)) { + if (session->packAdd_state == libssh2_NB_state_sent1) { + /* + * Remote wants new keys + * Well, it's already in the brigade, + * let's just call back into ourselves + */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Renegotiating Keys"); + + session->packAdd_state = libssh2_NB_state_sent2; + } + + /* + * The KEXINIT message has been added to the queue. The packAdd and + * readPack states need to be reset because _libssh2_kex_exchange + * (eventually) calls upon _libssh2_transport_read to read the rest of + * the key exchange conversation. + */ + session->readPack_state = libssh2_NB_state_idle; + session->packet.total_num = 0; + session->packAdd_state = libssh2_NB_state_idle; + session->fullpacket_state = libssh2_NB_state_idle; + + memset(&session->startup_key_state, 0, sizeof(key_exchange_state_t)); + + /* + * If there was a key reexchange failure, let's just hope we didn't + * send NEWKEYS yet, otherwise remote will drop us like a rock + */ + rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + session->packAdd_state = libssh2_NB_state_idle; + return 0; +} + +/* + * _libssh2_packet_ask + * + * Scan the brigade for a matching packet type, optionally poll the socket for + * a packet first + */ +int +_libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type, + unsigned char **data, size_t *data_len, + int match_ofs, const unsigned char *match_buf, + size_t match_len) +{ + LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets); + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Looking for packet of type: %d", (int) packet_type); + + while (packet) { + if (packet->data[0] == packet_type + && (packet->data_len >= (match_ofs + match_len)) + && (!match_buf || + (memcmp(packet->data + match_ofs, match_buf, + match_len) == 0))) { + *data = packet->data; + *data_len = packet->data_len; + + /* unlink struct from session->packets */ + _libssh2_list_remove(&packet->node); + + LIBSSH2_FREE(session, packet); + + return 0; + } + packet = _libssh2_list_next(&packet->node); + } + return -1; +} + +/* + * libssh2_packet_askv + * + * Scan for any of a list of packet types in the brigade, optionally poll the + * socket for a packet first + */ +int +_libssh2_packet_askv(LIBSSH2_SESSION * session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len) +{ + int i, packet_types_len = strlen((char *) packet_types); + + for(i = 0; i < packet_types_len; i++) { + if (0 == _libssh2_packet_ask(session, packet_types[i], data, + data_len, match_ofs, + match_buf, match_len)) { + return 0; + } + } + + return -1; +} + +/* + * _libssh2_packet_require + * + * Loops _libssh2_transport_read() until the packet requested is available + * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout + * + * Returns negative on error + * Returns 0 when it has taken care of the requested packet. + */ +int +_libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len, + packet_require_state_t *state) +{ + if (state->start == 0) { + if (_libssh2_packet_ask(session, packet_type, data, data_len, + match_ofs, match_buf, + match_len) == 0) { + /* A packet was available in the packet brigade */ + return 0; + } + + state->start = time(NULL); + } + + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + int ret = _libssh2_transport_read(session); + if (ret == LIBSSH2_ERROR_EAGAIN) + return ret; + else if (ret < 0) { + state->start = 0; + /* an error which is not just because of blocking */ + return ret; + } else if (ret == packet_type) { + /* Be lazy, let packet_ask pull it out of the brigade */ + ret = _libssh2_packet_ask(session, packet_type, data, data_len, + match_ofs, match_buf, match_len); + state->start = 0; + return ret; + } else if (ret == 0) { + /* nothing available, wait until data arrives or we time out */ + long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - + state->start); + + if (left <= 0) { + state->start = 0; + return LIBSSH2_ERROR_TIMEOUT; + } + return -1; /* no packet available yet */ + } + } + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* + * _libssh2_packet_burn + * + * Loops _libssh2_transport_read() until any packet is available and promptly + * discards it. + * Used during KEX exchange to discard badly guessed KEX_INIT packets + */ +int +_libssh2_packet_burn(LIBSSH2_SESSION * session, + libssh2_nonblocking_states * state) +{ + unsigned char *data; + size_t data_len; + unsigned char i, all_packets[255]; + int ret; + + if (*state == libssh2_NB_state_idle) { + for(i = 1; i < 255; i++) { + all_packets[i - 1] = i; + } + all_packets[254] = 0; + + if (_libssh2_packet_askv(session, all_packets, &data, &data_len, 0, + NULL, 0) == 0) { + i = data[0]; + /* A packet was available in the packet brigade, burn it */ + LIBSSH2_FREE(session, data); + return i; + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Blocking until packet becomes available to burn"); + *state = libssh2_NB_state_created; + } + + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + ret = _libssh2_transport_read(session); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } else if (ret < 0) { + *state = libssh2_NB_state_idle; + return ret; + } else if (ret == 0) { + /* FIXME: this might busyloop */ + continue; + } + + /* Be lazy, let packet_ask pull it out of the brigade */ + if (0 == + _libssh2_packet_ask(session, (unsigned char)ret, + &data, &data_len, 0, NULL, 0)) { + /* Smoke 'em if you got 'em */ + LIBSSH2_FREE(session, data); + *state = libssh2_NB_state_idle; + return ret; + } + } + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* + * _libssh2_packet_requirev + * + * Loops _libssh2_transport_read() until one of a list of packet types + * requested is available. SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause + * a bailout. packet_types is a null terminated list of packet_type numbers + */ + +int +_libssh2_packet_requirev(LIBSSH2_SESSION *session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, size_t match_len, + packet_requirev_state_t * state) +{ + if (_libssh2_packet_askv(session, packet_types, data, data_len, match_ofs, + match_buf, match_len) == 0) { + /* One of the packets listed was available in the packet brigade */ + state->start = 0; + return 0; + } + + if (state->start == 0) { + state->start = time(NULL); + } + + while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) { + int ret = _libssh2_transport_read(session); + if ((ret < 0) && (ret != LIBSSH2_ERROR_EAGAIN)) { + state->start = 0; + return ret; + } + if (ret <= 0) { + long left = LIBSSH2_READ_TIMEOUT - + (long)(time(NULL) - state->start); + + if (left <= 0) { + state->start = 0; + return LIBSSH2_ERROR_TIMEOUT; + } + else if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + } + + if (strchr((char *) packet_types, ret)) { + /* Be lazy, let packet_ask pull it out of the brigade */ + return _libssh2_packet_askv(session, packet_types, data, + data_len, match_ofs, match_buf, + match_len); + } + } + + /* Only reached if the socket died */ + state->start = 0; + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + diff --git a/libssh2/src/packet.h b/libssh2/src/packet.h new file mode 100644 index 000000000..d66b15b50 --- /dev/null +++ b/libssh2/src/packet.h @@ -0,0 +1,76 @@ +#ifndef LIBSSH2_PACKET_H +#define LIBSSH2_PACKET_H +/* + * Copyright (C) 2010 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + * + */ + +int _libssh2_packet_read(LIBSSH2_SESSION * session); + +int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len); + +int _libssh2_packet_askv(LIBSSH2_SESSION * session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len); +int _libssh2_packet_require(LIBSSH2_SESSION * session, + unsigned char packet_type, unsigned char **data, + size_t *data_len, int match_ofs, + const unsigned char *match_buf, + size_t match_len, + packet_require_state_t * state); +int _libssh2_packet_requirev(LIBSSH2_SESSION *session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len, + packet_requirev_state_t * state); +int _libssh2_packet_burn(LIBSSH2_SESSION * session, + libssh2_nonblocking_states * state); +int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long data_len); +int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, + size_t datalen, int macstate); + +#endif /* LIBSSH2_PACKET_H */ diff --git a/libssh2/src/pem.c b/libssh2/src/pem.c new file mode 100644 index 000000000..9f51bba3b --- /dev/null +++ b/libssh2/src/pem.c @@ -0,0 +1,324 @@ +/* Copyright (C) 2007 The Written Word, Inc. + * Copyright (C) 2008, Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +static int +readline(char *line, int line_size, FILE * fp) +{ + size_t len; + + if (!line) { + return -1; + } + if (!fgets(line, line_size, fp)) { + return -1; + } + + if (*line) { + len = strlen(line); + if (len > 0 && line[len - 1] == '\n') { + line[len - 1] = '\0'; + } + } + + if (*line) { + len = strlen(line); + if (len > 0 && line[len - 1] == '\r') { + line[len - 1] = '\0'; + } + } + + return 0; +} + +static int +readline_memory(char *line, size_t line_size, + const char *filedata, size_t filedata_len, + size_t *filedata_offset) +{ + size_t off, len; + + off = *filedata_offset; + + for (len = 0; off + len < filedata_len && len < line_size; len++) { + if (filedata[off + len] == '\n' || + filedata[off + len] == '\r') { + break; + } + } + + if (len) { + memcpy(line, filedata + off, len); + *filedata_offset += len; + } + + line[len] = '\0'; + *filedata_offset += 1; + + return 0; +} + +#define LINE_SIZE 128 + +int +_libssh2_pem_parse(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + FILE * fp, unsigned char **data, unsigned int *datalen) +{ + char line[LINE_SIZE]; + char *b64data = NULL; + unsigned int b64datalen = 0; + int ret; + + do { + *line = '\0'; + + if (readline(line, LINE_SIZE, fp)) { + return -1; + } + } + while (strcmp(line, headerbegin) != 0); + + *line = '\0'; + + do { + if (*line) { + char *tmp; + size_t linelen; + + linelen = strlen(line); + tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); + if (!tmp) { + ret = -1; + goto out; + } + memcpy(tmp + b64datalen, line, linelen); + b64data = tmp; + b64datalen += linelen; + } + + *line = '\0'; + + if (readline(line, LINE_SIZE, fp)) { + ret = -1; + goto out; + } + } while (strcmp(line, headerend) != 0); + + if (!b64data) { + return -1; + } + + if (libssh2_base64_decode(session, (char**) data, datalen, + b64data, b64datalen)) { + ret = -1; + goto out; + } + + ret = 0; + out: + if (b64data) { + LIBSSH2_FREE(session, b64data); + } + return ret; +} + +int +_libssh2_pem_parse_memory(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + const char *filedata, size_t filedata_len, + unsigned char **data, unsigned int *datalen) +{ + char line[LINE_SIZE]; + char *b64data = NULL; + unsigned int b64datalen = 0; + size_t off = 0; + int ret; + + do { + *line = '\0'; + + if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { + return -1; + } + } + while (strcmp(line, headerbegin) != 0); + + *line = '\0'; + + do { + if (*line) { + char *tmp; + size_t linelen; + + linelen = strlen(line); + tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); + if (!tmp) { + ret = -1; + goto out; + } + memcpy(tmp + b64datalen, line, linelen); + b64data = tmp; + b64datalen += linelen; + } + + *line = '\0'; + + if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { + ret = -1; + goto out; + } + } while (strcmp(line, headerend) != 0); + + if (!b64data) { + return -1; + } + + if (libssh2_base64_decode(session, (char**) data, datalen, + b64data, b64datalen)) { + ret = -1; + goto out; + } + + ret = 0; + out: + if (b64data) { + LIBSSH2_FREE(session, b64data); + } + return ret; +} + +static int +read_asn1_length(const unsigned char *data, + unsigned int datalen, unsigned int *len) +{ + unsigned int lenlen; + int nextpos; + + if (datalen < 1) { + return -1; + } + *len = data[0]; + + if (*len >= 0x80) { + lenlen = *len & 0x7F; + *len = data[1]; + if (1 + lenlen > datalen) { + return -1; + } + if (lenlen > 1) { + *len <<= 8; + *len |= data[2]; + } + } else { + lenlen = 0; + } + + nextpos = 1 + lenlen; + if (lenlen > 2 || 1 + lenlen + *len > datalen) { + return -1; + } + + return nextpos; +} + +int +_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen) +{ + unsigned int len; + int lenlen; + + if (*datalen < 1) { + return -1; + } + + if ((*data)[0] != '\x30') { + return -1; + } + + (*data)++; + (*datalen)--; + + lenlen = read_asn1_length(*data, *datalen, &len); + if (lenlen < 0 || lenlen + len != *datalen) { + return -1; + } + + *data += lenlen; + *datalen -= lenlen; + + return 0; +} + +int +_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen, + unsigned char **i, unsigned int *ilen) +{ + unsigned int len; + int lenlen; + + if (*datalen < 1) { + return -1; + } + + if ((*data)[0] != '\x02') { + return -1; + } + + (*data)++; + (*datalen)--; + + lenlen = read_asn1_length(*data, *datalen, &len); + if (lenlen < 0 || lenlen + len > *datalen) { + return -1; + } + + *data += lenlen; + *datalen -= lenlen; + + *i = *data; + *ilen = len; + + *data += len; + *datalen -= len; + + return 0; +} diff --git a/libssh2/src/publickey.c b/libssh2/src/publickey.c new file mode 100644 index 000000000..bfee0a842 --- /dev/null +++ b/libssh2/src/publickey.c @@ -0,0 +1,1059 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2010-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "libssh2_publickey.h" +#include "channel.h" +#include "session.h" + +#define LIBSSH2_PUBLICKEY_VERSION 2 + +/* Numericised response codes -- Not IETF, just local representation */ +#define LIBSSH2_PUBLICKEY_RESPONSE_STATUS 0 +#define LIBSSH2_PUBLICKEY_RESPONSE_VERSION 1 +#define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY 2 + +typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST +{ + int code; + const char *name; + int name_len; +} LIBSSH2_PUBLICKEY_CODE_LIST; + +static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_response_codes[] = +{ + {LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1}, + {LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1}, + {LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", + sizeof("publickey") - 1} , + {0, NULL, 0} +}; + +/* PUBLICKEY status codes -- IETF defined */ +#define LIBSSH2_PUBLICKEY_SUCCESS 0 +#define LIBSSH2_PUBLICKEY_ACCESS_DENIED 1 +#define LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED 2 +#define LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED 3 +#define LIBSSH2_PUBLICKEY_KEY_NOT_FOUND 4 +#define LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED 5 +#define LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT 6 +#define LIBSSH2_PUBLICKEY_GENERAL_FAILURE 7 +#define LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED 8 + +#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8 + +static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_status_codes[] = { + {LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1} , + {LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", + sizeof("access denied") - 1}, + {LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", + sizeof("storage exceeded") - 1} , + {LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported", + sizeof("version not supported") - 1} , + {LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found", + sizeof("key not found") - 1}, + {LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported", + sizeof("key not supported") - 1}, + {LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present", + sizeof("key already present") - 1}, + {LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure", + sizeof("general failure") - 1}, + {LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported", + sizeof("request not supported") - 1}, + {0, NULL, 0} +}; + +/* + * publickey_status_error + * + * Format an error message from a status code + */ +static void +publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, + LIBSSH2_SESSION *session, int status) +{ + const char *msg; + + /* GENERAL_FAILURE got remapped between version 1 and 2 */ + if (status == 6 && pkey && pkey->version == 1) { + status = 7; + } + + if (status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) { + msg = "unknown"; + } else { + msg = publickey_status_codes[status].name; + } + + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, msg); +} + +/* + * publickey_packet_receive + * + * Read a packet from the subsystem + */ +static int +publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey, + unsigned char **data, size_t *data_len) +{ + LIBSSH2_CHANNEL *channel = pkey->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned char buffer[4]; + int rc; + *data = NULL; /* default to nothing returned */ + *data_len = 0; + + if (pkey->receive_state == libssh2_NB_state_idle) { + rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc != 4) { + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid response from publickey subsystem"); + } + + pkey->receive_packet_len = _libssh2_ntohu32(buffer); + pkey->receive_packet = + LIBSSH2_ALLOC(session, pkey->receive_packet_len); + if (!pkey->receive_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate publickey response " + "buffer"); + } + + pkey->receive_state = libssh2_NB_state_sent; + } + + if (pkey->receive_state == libssh2_NB_state_sent) { + rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet, + pkey->receive_packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc != (int)pkey->receive_packet_len) { + LIBSSH2_FREE(session, pkey->receive_packet); + pkey->receive_packet = NULL; + pkey->receive_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for publickey subsystem " + "response packet"); + } + + *data = pkey->receive_packet; + *data_len = pkey->receive_packet_len; + } + + pkey->receive_state = libssh2_NB_state_idle; + + return 0; +} + +/* publickey_response_id + * + * Translate a string response name to a numeric code + * Data will be incremented by 4 + response_len on success only + */ +static int +publickey_response_id(unsigned char **pdata, size_t data_len) +{ + size_t response_len; + unsigned char *data = *pdata; + const LIBSSH2_PUBLICKEY_CODE_LIST *codes = publickey_response_codes; + + if (data_len < 4) { + /* Malformed response */ + return -1; + } + response_len = _libssh2_ntohu32(data); + data += 4; + data_len -= 4; + if (data_len < response_len) { + /* Malformed response */ + return -1; + } + + while (codes->name) { + if ((unsigned long)codes->name_len == response_len && + strncmp(codes->name, (char *) data, response_len) == 0) { + *pdata = data + response_len; + return codes->code; + } + codes++; + } + + return -1; +} + +/* publickey_response_success + * + * Generic helper routine to wait for success response and nothing else + */ +static int +publickey_response_success(LIBSSH2_PUBLICKEY * pkey) +{ + LIBSSH2_SESSION *session = pkey->channel->session; + unsigned char *data, *s; + size_t data_len; + int response; + + while (1) { + int rc = publickey_packet_receive(pkey, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from " + "publickey subsystem"); + } + + s = data; + response = publickey_response_id(&s, data_len); + + switch (response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error, or processing complete */ + { + unsigned long status = _libssh2_ntohu32(s); + + LIBSSH2_FREE(session, data); + + if (status == LIBSSH2_PUBLICKEY_SUCCESS) + return 0; + + publickey_status_error(pkey, session, status); + return -1; + } + default: + LIBSSH2_FREE(session, data); + if (response < 0) { + return _libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid publickey subsystem response"); + } + /* Unknown/Unexpected */ + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response"); + data = NULL; + } + } + /* never reached, but include `return` to silence compiler warnings */ + return -1; +} + +/* ***************** + * Publickey API * + ***************** */ + +/* + * publickey_init + * + * Startup the publickey subsystem + */ +static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session) +{ + int response; + int rc; + + if (session->pkeyInit_state == libssh2_NB_state_idle) { + session->pkeyInit_data = NULL; + session->pkeyInit_pkey = NULL; + session->pkeyInit_channel = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Initializing publickey subsystem"); + + session->pkeyInit_state = libssh2_NB_state_allocated; + } + + if (session->pkeyInit_state == libssh2_NB_state_allocated) { + + session->pkeyInit_channel = + _libssh2_channel_open(session, "session", + sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, + 0); + if (!session->pkeyInit_channel) { + if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) + /* The error state is already set, so leave it */ + return NULL; + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to startup channel"); + goto err_exit; + } + + session->pkeyInit_state = libssh2_NB_state_sent; + } + + if (session->pkeyInit_state == libssh2_NB_state_sent) { + rc = _libssh2_channel_process_startup(session->pkeyInit_channel, + "subsystem", + sizeof("subsystem") - 1, + "publickey", + sizeof("publickey") - 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting publickey subsystem"); + return NULL; + } else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to request publickey subsystem"); + goto err_exit; + } + + session->pkeyInit_state = libssh2_NB_state_sent1; + } + + if (session->pkeyInit_state == libssh2_NB_state_sent1) { + unsigned char *s; + rc = _libssh2_channel_extended_data(session->pkeyInit_channel, + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting publickey subsystem"); + return NULL; + } + + session->pkeyInit_pkey = + LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY)); + if (!session->pkeyInit_pkey) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a new publickey structure"); + goto err_exit; + } + session->pkeyInit_pkey->channel = session->pkeyInit_channel; + session->pkeyInit_pkey->version = 0; + + s = session->pkeyInit_buffer; + _libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4); + s += 4; + _libssh2_htonu32(s, sizeof("version") - 1); + s += 4; + memcpy(s, "version", sizeof("version") - 1); + s += sizeof("version") - 1; + _libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); + + session->pkeyInit_buffer_sent = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey advertising version %d support", + (int) LIBSSH2_PUBLICKEY_VERSION); + + session->pkeyInit_state = libssh2_NB_state_sent2; + } + + if (session->pkeyInit_state == libssh2_NB_state_sent2) { + rc = _libssh2_channel_write(session->pkeyInit_channel, 0, + session->pkeyInit_buffer, + 19 - session->pkeyInit_buffer_sent); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending publickey version packet"); + return NULL; + } else if (rc < 0) { + _libssh2_error(session, rc, + "Unable to send publickey version packet"); + goto err_exit; + } + session->pkeyInit_buffer_sent += rc; + if(session->pkeyInit_buffer_sent < 19) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Need to be called again to complete this"); + return NULL; + } + + session->pkeyInit_state = libssh2_NB_state_sent3; + } + + if (session->pkeyInit_state == libssh2_NB_state_sent3) { + while (1) { + unsigned char *s; + rc = publickey_packet_receive(session->pkeyInit_pkey, + &session->pkeyInit_data, + &session->pkeyInit_data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response from " + "publickey subsystem"); + return NULL; + } else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from " + "publickey subsystem"); + goto err_exit; + } + + s = session->pkeyInit_data; + if ((response = + publickey_response_id(&s, session->pkeyInit_data_len)) < 0) { + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid publickey subsystem response code"); + goto err_exit; + } + + switch (response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error */ + { + unsigned long status, descr_len, lang_len; + + status = _libssh2_ntohu32(s); + s += 4; + descr_len = _libssh2_ntohu32(s); + s += 4; + /* description starts here */ + s += descr_len; + lang_len = _libssh2_ntohu32(s); + s += 4; + /* lang starts here */ + s += lang_len; + + if (s > + session->pkeyInit_data + session->pkeyInit_data_len) { + _libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Malformed publickey subsystem packet"); + goto err_exit; + } + + publickey_status_error(NULL, session, status); + + goto err_exit; + } + + case LIBSSH2_PUBLICKEY_RESPONSE_VERSION: + /* What we want */ + session->pkeyInit_pkey->version = _libssh2_ntohu32(s); + if (session->pkeyInit_pkey->version > + LIBSSH2_PUBLICKEY_VERSION) { + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Truncate remote publickey version from %lu", + session->pkeyInit_pkey->version); + session->pkeyInit_pkey->version = + LIBSSH2_PUBLICKEY_VERSION; + } + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Enabling publickey subsystem version %lu", + session->pkeyInit_pkey->version); + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + session->pkeyInit_state = libssh2_NB_state_idle; + return session->pkeyInit_pkey; + + default: + /* Unknown/Unexpected */ + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response, " + "ignoring"); + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + } + } + } + + /* Never reached except by direct goto */ + err_exit: + session->pkeyInit_state = libssh2_NB_state_sent4; + if (session->pkeyInit_channel) { + rc = _libssh2_channel_close(session->pkeyInit_channel); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block closing channel"); + return NULL; + } + } + if (session->pkeyInit_pkey) { + LIBSSH2_FREE(session, session->pkeyInit_pkey); + session->pkeyInit_pkey = NULL; + } + if (session->pkeyInit_data) { + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + } + session->pkeyInit_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_publickey_init + * + * Startup the publickey subsystem + */ +LIBSSH2_API LIBSSH2_PUBLICKEY * +libssh2_publickey_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_PUBLICKEY *ptr; + + BLOCK_ADJUST_ERRNO(ptr, session, + publickey_init(session)); + return ptr; +} + + + +/* + * libssh2_publickey_add_ex + * + * Add a new public key entry + */ +LIBSSH2_API int +libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, + unsigned long name_len, const unsigned char *blob, + unsigned long blob_len, char overwrite, + unsigned long num_attrs, + const libssh2_publickey_attribute attrs[]) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_SESSION *session; + /* 19 = packet_len(4) + add_len(4) + "add"(3) + name_len(4) + {name} + blob_len(4) + {blob} */ + unsigned long i, packet_len = 19 + name_len + blob_len; + unsigned char *comment = NULL; + unsigned long comment_len = 0; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + channel = pkey->channel; + session = channel->session; + + if (pkey->add_state == libssh2_NB_state_idle) { + pkey->add_packet = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, "Adding %s publickey", + name); + + if (pkey->version == 1) { + for(i = 0; i < num_attrs; i++) { + /* Search for a comment attribute */ + if (attrs[i].name_len == (sizeof("comment") - 1) && + strncmp(attrs[i].name, "comment", + sizeof("comment") - 1) == 0) { + comment = (unsigned char *) attrs[i].value; + comment_len = attrs[i].value_len; + break; + } + } + packet_len += 4 + comment_len; + } else { + packet_len += 5; /* overwrite(1) + attribute_count(4) */ + for(i = 0; i < num_attrs; i++) { + packet_len += 9 + attrs[i].name_len + attrs[i].value_len; + /* name_len(4) + value_len(4) + mandatory(1) */ + } + } + + pkey->add_packet = LIBSSH2_ALLOC(session, packet_len); + if (!pkey->add_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey \"add\" packet"); + } + + pkey->add_s = pkey->add_packet; + _libssh2_htonu32(pkey->add_s, packet_len - 4); + pkey->add_s += 4; + _libssh2_htonu32(pkey->add_s, sizeof("add") - 1); + pkey->add_s += 4; + memcpy(pkey->add_s, "add", sizeof("add") - 1); + pkey->add_s += sizeof("add") - 1; + if (pkey->version == 1) { + _libssh2_htonu32(pkey->add_s, comment_len); + pkey->add_s += 4; + if (comment) { + memcpy(pkey->add_s, comment, comment_len); + pkey->add_s += comment_len; + } + + _libssh2_htonu32(pkey->add_s, name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, name, name_len); + pkey->add_s += name_len; + _libssh2_htonu32(pkey->add_s, blob_len); + pkey->add_s += 4; + memcpy(pkey->add_s, blob, blob_len); + pkey->add_s += blob_len; + } else { + /* Version == 2 */ + + _libssh2_htonu32(pkey->add_s, name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, name, name_len); + pkey->add_s += name_len; + _libssh2_htonu32(pkey->add_s, blob_len); + pkey->add_s += 4; + memcpy(pkey->add_s, blob, blob_len); + pkey->add_s += blob_len; + *(pkey->add_s++) = overwrite ? 0x01 : 0; + _libssh2_htonu32(pkey->add_s, num_attrs); + pkey->add_s += 4; + for(i = 0; i < num_attrs; i++) { + _libssh2_htonu32(pkey->add_s, attrs[i].name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len); + pkey->add_s += attrs[i].name_len; + _libssh2_htonu32(pkey->add_s, attrs[i].value_len); + pkey->add_s += 4; + memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len); + pkey->add_s += attrs[i].value_len; + *(pkey->add_s++) = attrs[i].mandatory ? 0x01 : 0; + } + } + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey \"add\" packet: " + "type=%s blob_len=%ld num_attrs=%ld", + name, blob_len, num_attrs); + + pkey->add_state = libssh2_NB_state_created; + } + + if (pkey->add_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, pkey->add_packet, + (pkey->add_s - pkey->add_packet)); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((pkey->add_s - pkey->add_packet) != rc) { + LIBSSH2_FREE(session, pkey->add_packet); + pkey->add_packet = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey add packet"); + } + LIBSSH2_FREE(session, pkey->add_packet); + pkey->add_packet = NULL; + + pkey->add_state = libssh2_NB_state_sent; + } + + rc = publickey_response_success(pkey); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + + pkey->add_state = libssh2_NB_state_idle; + + return rc; +} + +/* libssh2_publickey_remove_ex + * Remove an existing publickey so that authentication can no longer be + * performed using it + */ +LIBSSH2_API int +libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey, + const unsigned char *name, unsigned long name_len, + const unsigned char *blob, unsigned long blob_len) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_SESSION *session; + /* 22 = packet_len(4) + remove_len(4) + "remove"(6) + name_len(4) + {name} + + blob_len(4) + {blob} */ + unsigned long packet_len = 22 + name_len + blob_len; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + channel = pkey->channel; + session = channel->session; + + if (pkey->remove_state == libssh2_NB_state_idle) { + pkey->remove_packet = NULL; + + pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len); + if (!pkey->remove_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey \"remove\" packet"); + } + + pkey->remove_s = pkey->remove_packet; + _libssh2_htonu32(pkey->remove_s, packet_len - 4); + pkey->remove_s += 4; + _libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1); + pkey->remove_s += 4; + memcpy(pkey->remove_s, "remove", sizeof("remove") - 1); + pkey->remove_s += sizeof("remove") - 1; + _libssh2_htonu32(pkey->remove_s, name_len); + pkey->remove_s += 4; + memcpy(pkey->remove_s, name, name_len); + pkey->remove_s += name_len; + _libssh2_htonu32(pkey->remove_s, blob_len); + pkey->remove_s += 4; + memcpy(pkey->remove_s, blob, blob_len); + pkey->remove_s += blob_len; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey \"remove\" packet: " + "type=%s blob_len=%ld", + name, blob_len); + + pkey->remove_state = libssh2_NB_state_created; + } + + if (pkey->remove_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, pkey->remove_packet, + (pkey->remove_s - pkey->remove_packet)); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((pkey->remove_s - pkey->remove_packet) != rc) { + LIBSSH2_FREE(session, pkey->remove_packet); + pkey->remove_packet = NULL; + pkey->remove_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey remove packet"); + } + LIBSSH2_FREE(session, pkey->remove_packet); + pkey->remove_packet = NULL; + + pkey->remove_state = libssh2_NB_state_sent; + } + + rc = publickey_response_success(pkey); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + + pkey->remove_state = libssh2_NB_state_idle; + + return rc; +} + +/* libssh2_publickey_list_fetch + * Fetch a list of supported public key from a server + */ +LIBSSH2_API int +libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys, + libssh2_publickey_list ** pkey_list) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_SESSION *session; + libssh2_publickey_list *list = NULL; + unsigned long buffer_len = 12, keys = 0, max_keys = 0, i; + /* 12 = packet_len(4) + list_len(4) + "list"(4) */ + int response; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + channel = pkey->channel; + session = channel->session; + + if (pkey->listFetch_state == libssh2_NB_state_idle) { + pkey->listFetch_data = NULL; + + pkey->listFetch_s = pkey->listFetch_buffer; + _libssh2_htonu32(pkey->listFetch_s, buffer_len - 4); + pkey->listFetch_s += 4; + _libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1); + pkey->listFetch_s += 4; + memcpy(pkey->listFetch_s, "list", sizeof("list") - 1); + pkey->listFetch_s += sizeof("list") - 1; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey \"list\" packet"); + + pkey->listFetch_state = libssh2_NB_state_created; + } + + if (pkey->listFetch_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, + pkey->listFetch_buffer, + (pkey->listFetch_s - + pkey->listFetch_buffer)); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) { + pkey->listFetch_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey list packet"); + } + + pkey->listFetch_state = libssh2_NB_state_sent; + } + + while (1) { + rc = publickey_packet_receive(pkey, &pkey->listFetch_data, + &pkey->listFetch_data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from " + "publickey subsystem"); + goto err_exit; + } + + pkey->listFetch_s = pkey->listFetch_data; + if ((response = + publickey_response_id(&pkey->listFetch_s, + pkey->listFetch_data_len)) < 0) { + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid publickey subsystem response code"); + goto err_exit; + } + + switch (response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error, or processing complete */ + { + unsigned long status, descr_len, lang_len; + + status = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + descr_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + /* description starts at pkey->listFetch_s */ + pkey->listFetch_s += descr_len; + lang_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + /* lang starts at pkey->listFetch_s */ + pkey->listFetch_s += lang_len; + + if (pkey->listFetch_s > + pkey->listFetch_data + pkey->listFetch_data_len) { + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Malformed publickey subsystem packet"); + goto err_exit; + } + + if (status == LIBSSH2_PUBLICKEY_SUCCESS) { + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + *pkey_list = list; + *num_keys = keys; + pkey->listFetch_state = libssh2_NB_state_idle; + return 0; + } + + publickey_status_error(pkey, session, status); + goto err_exit; + } + case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY: + /* What we want */ + if (keys >= max_keys) { + libssh2_publickey_list *newlist; + /* Grow the key list if necessary */ + max_keys += 8; + newlist = + LIBSSH2_REALLOC(session, list, + (max_keys + + 1) * sizeof(libssh2_publickey_list)); + if (!newlist) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey list"); + goto err_exit; + } + list = newlist; + } + if (pkey->version == 1) { + unsigned long comment_len; + + comment_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + if (comment_len) { + list[keys].num_attrs = 1; + list[keys].attrs = + LIBSSH2_ALLOC(session, + sizeof(libssh2_publickey_attribute)); + if (!list[keys].attrs) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey attributes"); + goto err_exit; + } + list[keys].attrs[0].name = "comment"; + list[keys].attrs[0].name_len = sizeof("comment") - 1; + list[keys].attrs[0].value = (char *) pkey->listFetch_s; + list[keys].attrs[0].value_len = comment_len; + list[keys].attrs[0].mandatory = 0; + + pkey->listFetch_s += comment_len; + } else { + list[keys].num_attrs = 0; + list[keys].attrs = NULL; + } + list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].name = pkey->listFetch_s; + pkey->listFetch_s += list[keys].name_len; + list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].blob = pkey->listFetch_s; + pkey->listFetch_s += list[keys].blob_len; + } else { + /* Version == 2 */ + list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].name = pkey->listFetch_s; + pkey->listFetch_s += list[keys].name_len; + list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].blob = pkey->listFetch_s; + pkey->listFetch_s += list[keys].blob_len; + list[keys].num_attrs = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + if (list[keys].num_attrs) { + list[keys].attrs = + LIBSSH2_ALLOC(session, + list[keys].num_attrs * + sizeof(libssh2_publickey_attribute)); + if (!list[keys].attrs) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey attributes"); + goto err_exit; + } + for(i = 0; i < list[keys].num_attrs; i++) { + list[keys].attrs[i].name_len = + _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].attrs[i].name = (char *) pkey->listFetch_s; + pkey->listFetch_s += list[keys].attrs[i].name_len; + list[keys].attrs[i].value_len = + _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].attrs[i].value = (char *) pkey->listFetch_s; + pkey->listFetch_s += list[keys].attrs[i].value_len; + + /* actually an ignored value */ + list[keys].attrs[i].mandatory = 0; + } + } else { + list[keys].attrs = NULL; + } + } + /* To be FREEd in libssh2_publickey_list_free() */ + list[keys].packet = pkey->listFetch_data; + keys++; + + list[keys].packet = NULL; /* Terminate the list */ + pkey->listFetch_data = NULL; + break; + default: + /* Unknown/Unexpected */ + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response"); + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + } + } + + /* Only reached via explicit goto */ + err_exit: + if (pkey->listFetch_data) { + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + } + if (list) { + libssh2_publickey_list_free(pkey, list); + } + pkey->listFetch_state = libssh2_NB_state_idle; + return -1; +} + +/* libssh2_publickey_list_free + * Free a previously fetched list of public keys + */ +LIBSSH2_API void +libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey, + libssh2_publickey_list * pkey_list) +{ + LIBSSH2_SESSION *session; + libssh2_publickey_list *p = pkey_list; + + if(!pkey || !p) + return; + + session = pkey->channel->session; + + while (p->packet) { + if (p->attrs) { + LIBSSH2_FREE(session, p->attrs); + } + LIBSSH2_FREE(session, p->packet); + p++; + } + + LIBSSH2_FREE(session, pkey_list); +} + +/* libssh2_publickey_shutdown + * Shutdown the publickey subsystem + */ +LIBSSH2_API int +libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey) +{ + LIBSSH2_SESSION *session; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + session = pkey->channel->session; + + /* + * Make sure all memory used in the state variables are free + */ + if (pkey->receive_packet) { + LIBSSH2_FREE(session, pkey->receive_packet); + pkey->receive_packet = NULL; + } + if (pkey->add_packet) { + LIBSSH2_FREE(session, pkey->add_packet); + pkey->add_packet = NULL; + } + if (pkey->remove_packet) { + LIBSSH2_FREE(session, pkey->remove_packet); + pkey->remove_packet = NULL; + } + if (pkey->listFetch_data) { + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + } + + rc = _libssh2_channel_free(pkey->channel); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + LIBSSH2_FREE(session, pkey); + return 0; +} diff --git a/libssh2/src/scp.c b/libssh2/src/scp.c new file mode 100644 index 000000000..22778dd38 --- /dev/null +++ b/libssh2/src/scp.c @@ -0,0 +1,1126 @@ +/* Copyright (c) 2009-2010 by Daniel Stenberg + * Copyright (c) 2004-2008, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include +#include + +#include "channel.h" +#include "session.h" + + +/* Max. length of a quoted string after libssh2_shell_quotearg() processing */ +#define _libssh2_shell_quotedsize(s) (3 * strlen(s) + 2) + +/* + This function quotes a string in a way suitable to be used with a + shell, e.g. the file name + one two + becomes + 'one two' + + The resulting output string is crafted in a way that makes it usable + with the two most common shell types: Bourne Shell derived shells + (sh, ksh, ksh93, bash, zsh) and C-Shell derivates (csh, tcsh). + + The following special cases are handled: + o If the string contains an apostrophy itself, the apostrophy + character is written in quotation marks, e.g. "'". + The shell cannot handle the syntax 'doesn\'t', so we close the + current argument word, add the apostrophe in quotation marks "", + and open a new argument word instead (_ indicate the input + string characters): + _____ _ _ + 'doesn' "'" 't' + + Sequences of apostrophes are combined in one pair of quotation marks: + a'''b + becomes + _ ___ _ + 'a'"'''"'b' + + o If the string contains an exclamation mark (!), the C-Shell + interprets it as an event number. Using \! (not within quotation + marks or single quotation marks) is a mechanism understood by + both Bourne Shell and C-Shell. + + If a quotation was already started, the argument word is closed + first: + a!b + + become + _ _ _ + 'a'\!'b' + + The result buffer must be large enough for the expanded result. A + bad case regarding expansion is alternating characters and + apostrophes: + + a'b'c'd' (length 8) gets converted to + 'a'"'"'b'"'"'c'"'"'d'"'" (length 24) + + This is the worst case. + + Maximum length of the result: + 1 + 6 * (length(input) + 1) / 2) + 1 + + => 3 * length(input) + 2 + + Explanation: + o leading apostrophe + o one character / apostrophe pair (two characters) can get + represented as 6 characters: a' -> a'"'"' + o String terminator (+1) + + A result buffer three times the size of the input buffer + 2 + characters should be safe. + + References: + o csh-compatible quotation (special handling for '!' etc.), see + http://www.grymoire.com/Unix/Csh.html#toc-uh-10 + + Return value: + Length of the resulting string (not counting the terminating '\0'), + or 0 in case of errors, e.g. result buffer too small + + Note: this function could possible be used elsewhere within libssh2, but + until then it is kept static and in this source file. +*/ + +static unsigned +shell_quotearg(const char *path, unsigned char *buf, + unsigned bufsize) +{ + const char *src; + unsigned char *dst, *endp; + + /* + * Processing States: + * UQSTRING: unquoted string: ... -- used for quoting exclamation + * marks. This is the initial state + * SQSTRING: single-quoted-string: '... -- any character may follow + * QSTRING: quoted string: "... -- only apostrophes may follow + */ + enum { UQSTRING, SQSTRING, QSTRING } state = UQSTRING; + + endp = &buf[bufsize]; + src = path; + dst = buf; + while (*src && dst < endp - 1) { + + switch (*src) { + /* + * Special handling for apostrophe. + * An apostrophe is always written in quotation marks, e.g. + * ' -> "'". + */ + + case '\'': + switch (state) { + case UQSTRING: /* Unquoted string */ + if (dst+1 >= endp) + return 0; + *dst++ = '"'; + break; + case QSTRING: /* Continue quoted string */ + break; + case SQSTRING: /* Close single quoted string */ + if (dst+2 >= endp) + return 0; + *dst++ = '\''; + *dst++ = '"'; + break; + default: + break; + } + state = QSTRING; + break; + + /* + * Special handling for exclamation marks. CSH interprets + * exclamation marks even when quoted with apostrophes. We convert + * it to the plain string \!, because both Bourne Shell and CSH + * interpret that as a verbatim exclamation mark. + */ + + case '!': + switch (state) { + case UQSTRING: + if (dst+1 >= endp) + return 0; + *dst++ = '\\'; + break; + case QSTRING: + if (dst+2 >= endp) + return 0; + *dst++ = '"'; /* Closing quotation mark */ + *dst++ = '\\'; + break; + case SQSTRING: /* Close single quoted string */ + if (dst+2 >= endp) + return 0; + *dst++ = '\''; + *dst++ = '\\'; + break; + default: + break; + } + state = UQSTRING; + break; + + /* + * Ordinary character: prefer single-quoted string + */ + + default: + switch (state) { + case UQSTRING: + if (dst+1 >= endp) + return 0; + *dst++ = '\''; + break; + case QSTRING: + if (dst+2 >= endp) + return 0; + *dst++ = '"'; /* Closing quotation mark */ + *dst++ = '\''; + break; + case SQSTRING: /* Continue single quoted string */ + break; + default: + break; + } + state = SQSTRING; /* Start single-quoted string */ + break; + } + + if (dst+1 >= endp) + return 0; + *dst++ = *src++; + } + + switch (state) { + case UQSTRING: + break; + case QSTRING: /* Close quoted string */ + if (dst+1 >= endp) + return 0; + *dst++ = '"'; + break; + case SQSTRING: /* Close single quoted string */ + if (dst+1 >= endp) + return 0; + *dst++ = '\''; + break; + default: + break; + } + + if (dst+1 >= endp) + return 0; + *dst = '\0'; + + /* The result cannot be larger than 3 * strlen(path) + 2 */ + /* assert((dst - buf) <= (3 * (src - path) + 2)); */ + + return dst - buf; +} + +/* + * scp_recv + * + * Open a channel and request a remote file via SCP + * + */ +static LIBSSH2_CHANNEL * +scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb) +{ + int cmd_len; + int rc; + int tmp_err_code; + const char *tmp_err_msg; + + if (session->scpRecv_state == libssh2_NB_state_idle) { + session->scpRecv_mode = 0; + session->scpRecv_size = 0; + session->scpRecv_mtime = 0; + session->scpRecv_atime = 0; + + session->scpRecv_command_len = + _libssh2_shell_quotedsize(path) + sizeof("scp -f ") + (sb?1:0); + + session->scpRecv_command = + LIBSSH2_ALLOC(session, session->scpRecv_command_len); + + if (!session->scpRecv_command) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a command buffer for " + "SCP session"); + return NULL; + } + + snprintf((char *)session->scpRecv_command, + session->scpRecv_command_len, + "scp -%sf ", sb?"p":""); + + cmd_len = strlen((char *)session->scpRecv_command); + cmd_len += shell_quotearg(path, + &session->scpRecv_command[cmd_len], + session->scpRecv_command_len - cmd_len); + + session->scpRecv_command[cmd_len] = '\0'; + session->scpRecv_command_len = cmd_len + 1; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "Opening channel for SCP receive"); + + session->scpRecv_state = libssh2_NB_state_created; + } + + if (session->scpRecv_state == libssh2_NB_state_created) { + /* Allocate a channel */ + session->scpRecv_channel = + _libssh2_channel_open(session, "session", + sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, + 0); + if (!session->scpRecv_channel) { + if (libssh2_session_last_errno(session) != + LIBSSH2_ERROR_EAGAIN) { + LIBSSH2_FREE(session, session->scpRecv_command); + session->scpRecv_command = NULL; + session->scpRecv_state = libssh2_NB_state_idle; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel"); + } + return NULL; + } + + session->scpRecv_state = libssh2_NB_state_sent; + } + + if (session->scpRecv_state == libssh2_NB_state_sent) { + /* Request SCP for the desired file */ + rc = _libssh2_channel_process_startup(session->scpRecv_channel, "exec", + sizeof("exec") - 1, + (char *) session->scpRecv_command, + session->scpRecv_command_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting SCP startup"); + return NULL; + } else if (rc) { + LIBSSH2_FREE(session, session->scpRecv_command); + session->scpRecv_command = NULL; + goto scp_recv_error; + } + LIBSSH2_FREE(session, session->scpRecv_command); + session->scpRecv_command = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sending initial wakeup"); + /* SCP ACK */ + session->scpRecv_response[0] = '\0'; + + session->scpRecv_state = libssh2_NB_state_sent1; + } + + if (session->scpRecv_state == libssh2_NB_state_sent1) { + rc = _libssh2_channel_write(session->scpRecv_channel, 0, + session->scpRecv_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending initial wakeup"); + return NULL; + } else if (rc != 1) { + goto scp_recv_error; + } + + /* Parse SCP response */ + session->scpRecv_response_len = 0; + + session->scpRecv_state = libssh2_NB_state_sent2; + } + + if ((session->scpRecv_state == libssh2_NB_state_sent2) + || (session->scpRecv_state == libssh2_NB_state_sent3)) { + while (sb && (session->scpRecv_response_len < + LIBSSH2_SCP_RESPONSE_BUFLEN)) { + unsigned char *s, *p; + + if (session->scpRecv_state == libssh2_NB_state_sent2) { + rc = _libssh2_channel_read(session->scpRecv_channel, 0, + (char *) session-> + scpRecv_response + + session->scpRecv_response_len, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for SCP response"); + return NULL; + } + else if (rc < 0) { + /* error, give up */ + _libssh2_error(session, rc, "Failed reading SCP response"); + goto scp_recv_error; + } + else if(rc == 0) + goto scp_recv_empty_channel; + + session->scpRecv_response_len++; + + if (session->scpRecv_response[0] != 'T') { + size_t err_len; + char *err_msg; + + /* there can be + 01 for warnings + 02 for errors + + The following string MUST be newline terminated + */ + err_len = + _libssh2_channel_packet_data_len(session-> + scpRecv_channel, 0); + err_msg = LIBSSH2_ALLOC(session, err_len + 1); + if (!err_msg) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed to get memory "); + goto scp_recv_error; + } + + /* Read the remote error message */ + (void)_libssh2_channel_read(session->scpRecv_channel, 0, + err_msg, err_len); + /* If it failed for any reason, we ignore it anyway. */ + + /* zero terminate the error */ + err_msg[err_len]=0; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "got %02x %s", session->scpRecv_response[0], + err_msg); + + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Failed to recv file"); + + LIBSSH2_FREE(session, err_msg); + goto scp_recv_error; + } + + if ((session->scpRecv_response_len > 1) && + ((session-> + scpRecv_response[session->scpRecv_response_len - 1] < + '0') + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] > + '9')) + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + ' ') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\r') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid data in SCP response"); + goto scp_recv_error; + } + + if ((session->scpRecv_response_len < 9) + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + if (session->scpRecv_response_len == + LIBSSH2_SCP_RESPONSE_BUFLEN) { + /* You had your chance */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unterminated response from SCP server"); + goto scp_recv_error; + } + /* Way too short to be an SCP response, or not done yet, + short circuit */ + continue; + } + + /* We're guaranteed not to go under response_len == 0 by the + logic above */ + while ((session-> + scpRecv_response[session->scpRecv_response_len - 1] == + '\r') + || (session-> + scpRecv_response[session->scpRecv_response_len - + 1] == '\n')) + session->scpRecv_response_len--; + session->scpRecv_response[session->scpRecv_response_len] = + '\0'; + + if (session->scpRecv_response_len < 8) { + /* EOL came too soon */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "too short" ); + goto scp_recv_error; + } + + s = session->scpRecv_response + 1; + + p = (unsigned char *) strchr((char *) s, ' '); + if (!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "malformed mtime"); + goto scp_recv_error; + } + + *(p++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + session->scpRecv_mtime = strtol((char *) s, NULL, 10); + + s = (unsigned char *) strchr((char *) p, ' '); + if (!s || ((s - p) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, malformed mtime.usec"); + goto scp_recv_error; + } + + /* Ignore mtime.usec */ + s++; + p = (unsigned char *) strchr((char *) s, ' '); + if (!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short or malformed"); + goto scp_recv_error; + } + + *p = '\0'; + /* Make sure we don't get fooled by leftover values */ + session->scpRecv_atime = strtol((char *) s, NULL, 10); + + /* SCP ACK */ + session->scpRecv_response[0] = '\0'; + + session->scpRecv_state = libssh2_NB_state_sent3; + } + + if (session->scpRecv_state == libssh2_NB_state_sent3) { + rc = _libssh2_channel_write(session->scpRecv_channel, 0, + session->scpRecv_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting to send SCP ACK"); + return NULL; + } else if (rc != 1) { + goto scp_recv_error; + } + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "mtime = %ld, atime = %ld", + session->scpRecv_mtime, session->scpRecv_atime); + + /* We *should* check that atime.usec is valid, but why let + that stop use? */ + break; + } + } + + session->scpRecv_state = libssh2_NB_state_sent4; + } + + if (session->scpRecv_state == libssh2_NB_state_sent4) { + session->scpRecv_response_len = 0; + + session->scpRecv_state = libssh2_NB_state_sent5; + } + + if ((session->scpRecv_state == libssh2_NB_state_sent5) + || (session->scpRecv_state == libssh2_NB_state_sent6)) { + while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { + char *s, *p, *e = NULL; + + if (session->scpRecv_state == libssh2_NB_state_sent5) { + rc = _libssh2_channel_read(session->scpRecv_channel, 0, + (char *) session-> + scpRecv_response + + session->scpRecv_response_len, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for SCP response"); + return NULL; + } + else if (rc < 0) { + /* error, bail out*/ + _libssh2_error(session, rc, "Failed reading SCP response"); + goto scp_recv_error; + } + else if(rc == 0) + goto scp_recv_empty_channel; + + session->scpRecv_response_len++; + + if (session->scpRecv_response[0] != 'C') { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server"); + goto scp_recv_error; + } + + if ((session->scpRecv_response_len > 1) && + (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\r') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n') + && + (session-> + scpRecv_response[session->scpRecv_response_len - 1] + < 32)) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid data in SCP response"); + goto scp_recv_error; + } + + if ((session->scpRecv_response_len < 7) + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + if (session->scpRecv_response_len == + LIBSSH2_SCP_RESPONSE_BUFLEN) { + /* You had your chance */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unterminated response from SCP server"); + goto scp_recv_error; + } + /* Way too short to be an SCP response, or not done yet, + short circuit */ + continue; + } + + /* We're guaranteed not to go under response_len == 0 by the + logic above */ + while ((session-> + scpRecv_response[session->scpRecv_response_len - 1] == + '\r') + || (session-> + scpRecv_response[session->scpRecv_response_len - + 1] == '\n')) { + session->scpRecv_response_len--; + } + session->scpRecv_response[session->scpRecv_response_len] = + '\0'; + + if (session->scpRecv_response_len < 6) { + /* EOL came too soon */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short"); + goto scp_recv_error; + } + + s = (char *) session->scpRecv_response + 1; + + p = strchr(s, ' '); + if (!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, malformed mode"); + goto scp_recv_error; + } + + *(p++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + + session->scpRecv_mode = strtol(s, &e, 8); + if (e && *e) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, invalid mode"); + goto scp_recv_error; + } + + s = strchr(p, ' '); + if (!s || ((s - p) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short or malformed"); + goto scp_recv_error; + } + + *s = '\0'; + /* Make sure we don't get fooled by leftover values */ + session->scpRecv_size = scpsize_strtol(p, &e, 10); + if (e && *e) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, invalid size"); + goto scp_recv_error; + } + + /* SCP ACK */ + session->scpRecv_response[0] = '\0'; + + session->scpRecv_state = libssh2_NB_state_sent6; + } + + if (session->scpRecv_state == libssh2_NB_state_sent6) { + rc = _libssh2_channel_write(session->scpRecv_channel, 0, + session->scpRecv_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending SCP ACK"); + return NULL; + } else if (rc != 1) { + goto scp_recv_error; + } + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "mode = 0%lo size = %ld", session->scpRecv_mode, + session->scpRecv_size); + + /* We *should* check that basename is valid, but why let that + stop us? */ + break; + } + } + + session->scpRecv_state = libssh2_NB_state_sent7; + } + + if (sb) { + memset(sb, 0, sizeof(libssh2_struct_stat)); + + sb->st_mtime = session->scpRecv_mtime; + sb->st_atime = session->scpRecv_atime; + sb->st_size = session->scpRecv_size; + sb->st_mode = (unsigned short)session->scpRecv_mode; + } + + session->scpRecv_state = libssh2_NB_state_idle; + return session->scpRecv_channel; + + scp_recv_empty_channel: + /* the code only jumps here as a result of a zero read from channel_read() + so we check EOF status to avoid getting stuck in a loop */ + if(libssh2_channel_eof(session->scpRecv_channel)) + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unexpected channel close"); + else + return session->scpRecv_channel; + /* fall-through */ + scp_recv_error: + tmp_err_code = session->err_code; + tmp_err_msg = session->err_msg; + while (libssh2_channel_free(session->scpRecv_channel) == + LIBSSH2_ERROR_EAGAIN); + session->err_code = tmp_err_code; + session->err_msg = tmp_err_msg; + session->scpRecv_channel = NULL; + session->scpRecv_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_scp_recv + * + * DEPRECATED + * + * Open a channel and request a remote file via SCP. This receives files larger + * than 2 GB, but is unable to report the proper size on platforms where the + * st_size member of struct stat is limited to 2 GB (e.g. windows). + * + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat * sb) +{ + LIBSSH2_CHANNEL *ptr; + + /* scp_recv uses libssh2_struct_stat, so pass one if the caller gave us a struct to populate... */ + libssh2_struct_stat sb_intl; + libssh2_struct_stat *sb_ptr; + sb_ptr = sb ? &sb_intl : NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb_ptr)); + + /* ...and populate the caller's with as much info as fits. */ + if (sb) { + memset(sb, 0, sizeof(struct stat)); + + sb->st_mtime = sb_intl.st_mtime; + sb->st_atime = sb_intl.st_atime; + sb->st_size = (off_t)sb_intl.st_size; + sb->st_mode = sb_intl.st_mode; + } + + return ptr; +} + +/* + * libssh2_scp_recv2 + * + * Open a channel and request a remote file via SCP. This supports files > 2GB + * on platforms that support it. + * + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_recv2(LIBSSH2_SESSION *session, const char *path, libssh2_struct_stat * sb) +{ + LIBSSH2_CHANNEL *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb)); + return ptr; +} + +/* + * scp_send() + * + * Send a file using SCP + * + */ +static LIBSSH2_CHANNEL * +scp_send(LIBSSH2_SESSION * session, const char *path, int mode, + libssh2_int64_t size, time_t mtime, time_t atime) +{ + int cmd_len; + int rc; + int tmp_err_code; + const char *tmp_err_msg; + + if (session->scpSend_state == libssh2_NB_state_idle) { + session->scpSend_command_len = + _libssh2_shell_quotedsize(path) + sizeof("scp -t ") + + ((mtime || atime)?1:0); + + session->scpSend_command = + LIBSSH2_ALLOC(session, session->scpSend_command_len); + + if (!session->scpSend_command) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a command buffer for " + "SCP session"); + return NULL; + } + + snprintf((char *)session->scpSend_command, + session->scpSend_command_len, + "scp -%st ", (mtime || atime)?"p":""); + + cmd_len = strlen((char *)session->scpSend_command); + cmd_len += shell_quotearg(path, + &session->scpSend_command[cmd_len], + session->scpSend_command_len - cmd_len); + + session->scpSend_command[cmd_len] = '\0'; + session->scpSend_command_len = cmd_len + 1; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "Opening channel for SCP send"); + /* Allocate a channel */ + + session->scpSend_state = libssh2_NB_state_created; + } + + if (session->scpSend_state == libssh2_NB_state_created) { + session->scpSend_channel = + _libssh2_channel_open(session, "session", sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); + if (!session->scpSend_channel) { + if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { + /* previous call set libssh2_session_last_error(), pass it + through */ + LIBSSH2_FREE(session, session->scpSend_command); + session->scpSend_command = NULL; + session->scpSend_state = libssh2_NB_state_idle; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel"); + } + return NULL; + } + + session->scpSend_state = libssh2_NB_state_sent; + } + + if (session->scpSend_state == libssh2_NB_state_sent) { + /* Request SCP for the desired file */ + rc = _libssh2_channel_process_startup(session->scpSend_channel, "exec", + sizeof("exec") - 1, + (char *) session->scpSend_command, + session->scpSend_command_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting SCP startup"); + return NULL; + } + else if (rc) { + /* previous call set libssh2_session_last_error(), pass it + through */ + LIBSSH2_FREE(session, session->scpSend_command); + session->scpSend_command = NULL; + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unknown error while getting error string"); + goto scp_send_error; + } + LIBSSH2_FREE(session, session->scpSend_command); + session->scpSend_command = NULL; + + session->scpSend_state = libssh2_NB_state_sent1; + } + + if (session->scpSend_state == libssh2_NB_state_sent1) { + /* Wait for ACK */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response from remote"); + return NULL; + } + else if (rc < 0) { + _libssh2_error(session, rc, "SCP failure"); + goto scp_send_error; + } + else if(!rc) + /* remain in the same state */ + goto scp_send_empty_channel; + else if (session->scpSend_response[0] != 0) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote"); + goto scp_send_error; + } + if (mtime || atime) { + /* Send mtime and atime to be used for file */ + session->scpSend_response_len = + snprintf((char *) session->scpSend_response, + LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", + (long)mtime, (long)atime); + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s", + session->scpSend_response); + } + + session->scpSend_state = libssh2_NB_state_sent2; + } + + /* Send mtime and atime to be used for file */ + if (mtime || atime) { + if (session->scpSend_state == libssh2_NB_state_sent2) { + rc = _libssh2_channel_write(session->scpSend_channel, 0, + session->scpSend_response, + session->scpSend_response_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending time data for SCP file"); + return NULL; + } else if (rc != (int)session->scpSend_response_len) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send time data for SCP file"); + goto scp_send_error; + } + + session->scpSend_state = libssh2_NB_state_sent3; + } + + if (session->scpSend_state == libssh2_NB_state_sent3) { + /* Wait for ACK */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response"); + return NULL; + } + else if (rc < 0) { + _libssh2_error(session, rc, "SCP failure"); + goto scp_send_error; + } + else if(!rc) + /* remain in the same state */ + goto scp_send_empty_channel; + else if (session->scpSend_response[0] != 0) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid SCP ACK response"); + goto scp_send_error; + } + + session->scpSend_state = libssh2_NB_state_sent4; + } + } else { + if (session->scpSend_state == libssh2_NB_state_sent2) { + session->scpSend_state = libssh2_NB_state_sent4; + } + } + + if (session->scpSend_state == libssh2_NB_state_sent4) { + /* Send mode, size, and basename */ + const char *base = strrchr(path, '/'); + if (base) + base++; + else + base = path; + + session->scpSend_response_len = + snprintf((char *) session->scpSend_response, + LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %" + LIBSSH2_INT64_T_FORMAT " %s\n", mode, + size, base); + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s", + session->scpSend_response); + + session->scpSend_state = libssh2_NB_state_sent5; + } + + if (session->scpSend_state == libssh2_NB_state_sent5) { + rc = _libssh2_channel_write(session->scpSend_channel, 0, + session->scpSend_response, + session->scpSend_response_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block send core file data for SCP file"); + return NULL; + } else if (rc != (int)session->scpSend_response_len) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send core file data for SCP file"); + goto scp_send_error; + } + + session->scpSend_state = libssh2_NB_state_sent6; + } + + if (session->scpSend_state == libssh2_NB_state_sent6) { + /* Wait for ACK */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response"); + return NULL; + } + else if (rc < 0) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote"); + goto scp_send_error; + } + else if (rc == 0) + goto scp_send_empty_channel; + + else if (session->scpSend_response[0] != 0) { + size_t err_len; + char *err_msg; + + err_len = + _libssh2_channel_packet_data_len(session->scpSend_channel, 0); + err_msg = LIBSSH2_ALLOC(session, err_len + 1); + if (!err_msg) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "failed to get memory"); + goto scp_send_error; + } + + /* Read the remote error message */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + err_msg, err_len); + if (rc > 0) { + err_msg[err_len]=0; + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "got %02x %s", session->scpSend_response[0], + err_msg); + } + LIBSSH2_FREE(session, err_msg); + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "failed to send file"); + goto scp_send_error; + } + } + + session->scpSend_state = libssh2_NB_state_idle; + return session->scpSend_channel; + + scp_send_empty_channel: + /* the code only jumps here as a result of a zero read from channel_read() + so we check EOF status to avoid getting stuck in a loop */ + if(libssh2_channel_eof(session->scpSend_channel)) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unexpected channel close"); + } + else + return session->scpSend_channel; + /* fall-through */ + scp_send_error: + tmp_err_code = session->err_code; + tmp_err_msg = session->err_msg; + while (libssh2_channel_free(session->scpSend_channel) == + LIBSSH2_ERROR_EAGAIN); + session->err_code = tmp_err_code; + session->err_msg = tmp_err_msg; + session->scpSend_channel = NULL; + session->scpSend_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_scp_send_ex + * + * Send a file using SCP. Old API. + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, + size_t size, long mtime, long atime) +{ + LIBSSH2_CHANNEL *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, + scp_send(session, path, mode, size, + (time_t)mtime, (time_t)atime)); + return ptr; +} + +/* + * libssh2_scp_send64 + * + * Send a file using SCP + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode, + libssh2_int64_t size, time_t mtime, time_t atime) +{ + LIBSSH2_CHANNEL *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, + scp_send(session, path, mode, size, mtime, atime)); + return ptr; +} diff --git a/libssh2/src/session.c b/libssh2/src/session.c new file mode 100644 index 000000000..6352d12ee --- /dev/null +++ b/libssh2/src/session.c @@ -0,0 +1,1794 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2009-2015 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +#ifdef HAVE_GETTIMEOFDAY +#include +#endif +#ifdef HAVE_ALLOCA_H +#include +#endif + +#include "transport.h" +#include "session.h" +#include "channel.h" +#include "mac.h" +#include "misc.h" + +/* libssh2_default_alloc + */ +static +LIBSSH2_ALLOC_FUNC(libssh2_default_alloc) +{ + (void) abstract; + return malloc(count); +} + +/* libssh2_default_free + */ +static +LIBSSH2_FREE_FUNC(libssh2_default_free) +{ + (void) abstract; + free(ptr); +} + +/* libssh2_default_realloc + */ +static +LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) +{ + (void) abstract; + return realloc(ptr, count); +} + +/* + * banner_receive + * + * Wait for a hello from the remote host + * Allocate a buffer and store the banner in session->remote.banner + * Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative + * on failure + */ +static int +banner_receive(LIBSSH2_SESSION * session) +{ + int ret; + int banner_len; + + if (session->banner_TxRx_state == libssh2_NB_state_idle) { + banner_len = 0; + + session->banner_TxRx_state = libssh2_NB_state_created; + } else { + banner_len = session->banner_TxRx_total_send; + } + + while ((banner_len < (int) sizeof(session->banner_TxRx_banner)) && + ((banner_len == 0) + || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) { + char c = '\0'; + + /* no incoming block yet! */ + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; + + ret = LIBSSH2_RECV(session, &c, 1, + LIBSSH2_SOCKET_RECV_FLAGS(session)); + if (ret < 0) { + if(session->api_block_mode || (ret != -EAGAIN)) + /* ignore EAGAIN when non-blocking */ + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error recving %d bytes: %d", 1, -ret); + } + else + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Recved %d bytes banner", ret); + + if (ret < 0) { + if (ret == -EAGAIN) { + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_INBOUND; + session->banner_TxRx_total_send = banner_len; + return LIBSSH2_ERROR_EAGAIN; + } + + /* Some kinda error */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + return LIBSSH2_ERROR_SOCKET_RECV; + } + + if (ret == 0) { + session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; + return LIBSSH2_ERROR_SOCKET_DISCONNECT; + } + + if (c == '\0') { + /* NULLs are not allowed in SSH banners */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + return LIBSSH2_ERROR_BANNER_RECV; + } + + session->banner_TxRx_banner[banner_len++] = c; + } + + while (banner_len && + ((session->banner_TxRx_banner[banner_len - 1] == '\n') || + (session->banner_TxRx_banner[banner_len - 1] == '\r'))) { + banner_len--; + } + + /* From this point on, we are done here */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + + if (!banner_len) + return LIBSSH2_ERROR_BANNER_RECV; + + session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1); + if (!session->remote.banner) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Error allocating space for remote banner"); + } + memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len); + session->remote.banner[banner_len] = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Received Banner: %s", + session->remote.banner); + return LIBSSH2_ERROR_NONE; +} + +/* + * banner_send + * + * Send the default banner, or the one set via libssh2_setopt_string + * + * Returns LIBSSH2_ERROR_EAGAIN if it would block - and if it does so, you + * should call this function again as soon as it is likely that more data can + * be sent, and this function should then be called with the same argument set + * (same data pointer and same data_len) until zero or failure is returned. + */ +static int +banner_send(LIBSSH2_SESSION * session) +{ + char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF; + int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1; + ssize_t ret; +#ifdef LIBSSH2DEBUG + char banner_dup[256]; +#endif + + if (session->banner_TxRx_state == libssh2_NB_state_idle) { + if (session->local.banner) { + /* setopt_string will have given us our \r\n characters */ + banner_len = strlen((char *) session->local.banner); + banner = (char *) session->local.banner; + } +#ifdef LIBSSH2DEBUG + /* Hack and slash to avoid sending CRLF in debug output */ + if (banner_len < 256) { + memcpy(banner_dup, banner, banner_len - 2); + banner_dup[banner_len - 2] = '\0'; + } else { + memcpy(banner_dup, banner, 255); + banner[255] = '\0'; + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Sending Banner: %s", + banner_dup); +#endif + + session->banner_TxRx_state = libssh2_NB_state_created; + } + + /* no outgoing block yet! */ + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; + + ret = LIBSSH2_SEND(session, + banner + session->banner_TxRx_total_send, + banner_len - session->banner_TxRx_total_send, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if (ret < 0) + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error sending %d bytes: %d", + banner_len - session->banner_TxRx_total_send, -ret); + else + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Sent %d/%d bytes at %p+%d", ret, + banner_len - session->banner_TxRx_total_send, + banner, session->banner_TxRx_total_send); + + if (ret != (banner_len - session->banner_TxRx_total_send)) { + if (ret >= 0 || ret == -EAGAIN) { + /* the whole packet could not be sent, save the what was */ + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_OUTBOUND; + if (ret > 0) + session->banner_TxRx_total_send += ret; + return LIBSSH2_ERROR_EAGAIN; + } + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + return LIBSSH2_ERROR_SOCKET_RECV; + } + + /* Set the state back to idle */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + + return 0; +} + +/* + * session_nonblock() sets the given socket to either blocking or + * non-blocking mode based on the 'nonblock' boolean argument. This function + * is copied from the libcurl sources with permission. + */ +static int +session_nonblock(libssh2_socket_t sockfd, /* operate on this */ + int nonblock /* TRUE or FALSE */ ) +{ +#undef SETBLOCK +#define SETBLOCK 0 +#ifdef HAVE_O_NONBLOCK + /* most recent unix versions */ + int flags; + + flags = fcntl(sockfd, F_GETFL, 0); + if (nonblock) + return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + else + return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); +#undef SETBLOCK +#define SETBLOCK 1 +#endif + +#if defined(HAVE_FIONBIO) && (SETBLOCK == 0) + /* older unix versions and VMS*/ + int flags; + + flags = nonblock; + return ioctl(sockfd, FIONBIO, &flags); +#undef SETBLOCK +#define SETBLOCK 2 +#endif + +#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0) + /* Windows? */ + unsigned long flags; + flags = nonblock; + + return ioctlsocket(sockfd, FIONBIO, &flags); +#undef SETBLOCK +#define SETBLOCK 3 +#endif + +#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0) + /* presumably for Amiga */ + return IoctlSocket(sockfd, FIONBIO, (long) nonblock); +#undef SETBLOCK +#define SETBLOCK 4 +#endif + +#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0) + /* BeOS */ + long b = nonblock ? 1 : 0; + return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); +#undef SETBLOCK +#define SETBLOCK 5 +#endif + +#ifdef HAVE_DISABLED_NONBLOCKING + return 0; /* returns success */ +#undef SETBLOCK +#define SETBLOCK 6 +#endif + +#if (SETBLOCK == 0) +#error "no non-blocking method was found/used/set" +#endif +} + +/* + * get_socket_nonblocking() + * + * gets the given blocking or non-blocking state of the socket. + */ +static int +get_socket_nonblocking(int sockfd) +{ /* operate on this */ +#undef GETBLOCK +#define GETBLOCK 0 +#ifdef HAVE_O_NONBLOCK + /* most recent unix versions */ + int flags; + + if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) { + /* Assume blocking on error */ + return 1; + } + return (flags & O_NONBLOCK); +#undef GETBLOCK +#define GETBLOCK 1 +#endif + +#if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0) + /* Windows? */ + unsigned int option_value; + socklen_t option_len = sizeof(option_value); + + if (getsockopt + (sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) { + /* Assume blocking on error */ + return 1; + } + return (int) option_value; +#undef GETBLOCK +#define GETBLOCK 2 +#endif + +#if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0) + /* BeOS */ + long b; + if (getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) { + /* Assume blocking on error */ + return 1; + } + return (int) b; +#undef GETBLOCK +#define GETBLOCK 5 +#endif + +#if defined(SO_STATE) && defined( __VMS ) && (GETBLOCK == 0) + + /* VMS TCP/IP Services */ + + size_t sockstat = 0; + int callstat = 0; + size_t size = sizeof( int ); + + callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE, + (char *)&sockstat, &size); + if ( callstat == -1 ) return(0); + if ( (sockstat&SS_NBIO) )return(1); + return(0); + +#undef GETBLOCK +#define GETBLOCK 6 +#endif + +#ifdef HAVE_DISABLED_NONBLOCKING + return 1; /* returns blocking */ +#undef GETBLOCK +#define GETBLOCK 7 +#endif + +#if (GETBLOCK == 0) +#error "no non-blocking method was found/used/get" +#endif +} + +/* libssh2_session_banner_set + * Set the local banner to use in the server handshake. + */ +LIBSSH2_API int +libssh2_session_banner_set(LIBSSH2_SESSION * session, const char *banner) +{ + size_t banner_len = banner ? strlen(banner) : 0; + + if (session->local.banner) { + LIBSSH2_FREE(session, session->local.banner); + session->local.banner = NULL; + } + + if (!banner_len) + return 0; + + session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3); + if (!session->local.banner) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for local banner"); + } + + memcpy(session->local.banner, banner, banner_len); + + /* first zero terminate like this so that the debug output is nice */ + session->local.banner[banner_len] = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s", + session->local.banner); + session->local.banner[banner_len++] = '\r'; + session->local.banner[banner_len++] = '\n'; + session->local.banner[banner_len] = '\0'; + + return 0; +} + +/* libssh2_banner_set + * Set the local banner. DEPRECATED VERSION + */ +LIBSSH2_API int +libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner) +{ + return libssh2_session_banner_set(session, banner); +} + +/* + * libssh2_session_init_ex + * + * Allocate and initialize a libssh2 session structure. Allows for malloc + * callbacks in case the calling program has its own memory manager It's + * allowable (but unadvisable) to define some but not all of the malloc + * callbacks An additional pointer value may be optionally passed to be sent + * to the callbacks (so they know who's asking) + */ +LIBSSH2_API LIBSSH2_SESSION * +libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), + LIBSSH2_FREE_FUNC((*my_free)), + LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract) +{ + LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc; + LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free; + LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc; + LIBSSH2_SESSION *session; + + if (my_alloc) { + local_alloc = my_alloc; + } + if (my_free) { + local_free = my_free; + } + if (my_realloc) { + local_realloc = my_realloc; + } + + session = local_alloc(sizeof(LIBSSH2_SESSION), &abstract); + if (session) { + memset(session, 0, sizeof(LIBSSH2_SESSION)); + session->alloc = local_alloc; + session->free = local_free; + session->realloc = local_realloc; + session->send = _libssh2_send; + session->recv = _libssh2_recv; + session->abstract = abstract; + session->api_timeout = 0; /* timeout-free API by default */ + session->api_block_mode = 1; /* blocking API by default */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "New session resource allocated"); + _libssh2_init_if_needed (); + } + return session; +} + +/* + * libssh2_session_callback_set + * + * Set (or reset) a callback function + * Returns the prior address + * + * FIXME: this function relies on that we can typecast function pointers + * to void pointers, which isn't allowed in ISO C! + */ +LIBSSH2_API void * +libssh2_session_callback_set(LIBSSH2_SESSION * session, + int cbtype, void *callback) +{ + void *oldcb; + + switch (cbtype) { + case LIBSSH2_CALLBACK_IGNORE: + oldcb = session->ssh_msg_ignore; + session->ssh_msg_ignore = callback; + return oldcb; + + case LIBSSH2_CALLBACK_DEBUG: + oldcb = session->ssh_msg_debug; + session->ssh_msg_debug = callback; + return oldcb; + + case LIBSSH2_CALLBACK_DISCONNECT: + oldcb = session->ssh_msg_disconnect; + session->ssh_msg_disconnect = callback; + return oldcb; + + case LIBSSH2_CALLBACK_MACERROR: + oldcb = session->macerror; + session->macerror = callback; + return oldcb; + + case LIBSSH2_CALLBACK_X11: + oldcb = session->x11; + session->x11 = callback; + return oldcb; + + case LIBSSH2_CALLBACK_SEND: + oldcb = session->send; + session->send = callback; + return oldcb; + + case LIBSSH2_CALLBACK_RECV: + oldcb = session->recv; + session->recv = callback; + return oldcb; + } + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d", cbtype); + + return NULL; +} + +/* + * _libssh2_wait_socket() + * + * Utility function that waits for action on the socket. Returns 0 when ready + * to run again or error on timeout. + */ +int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time) +{ + int rc; + int seconds_to_next; + int dir; + int has_timeout; + long ms_to_next = 0; + long elapsed_ms; + + /* since libssh2 often sets EAGAIN internally before this function is + called, we can decrease some amount of confusion in user programs by + resetting the error code in this function to reduce the risk of EAGAIN + being stored as error when a blocking function has returned */ + session->err_code = LIBSSH2_ERROR_NONE; + + rc = libssh2_keepalive_send (session, &seconds_to_next); + if (rc < 0) + return rc; + + ms_to_next = seconds_to_next * 1000; + + /* figure out what to wait for */ + dir = libssh2_session_block_directions(session); + + if(!dir) { + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Nothing to wait for in wait_socket"); + /* To avoid that we hang below just because there's nothing set to + wait for, we timeout on 1 second to also avoid busy-looping + during this condition */ + ms_to_next = 1000; + } + + if (session->api_timeout > 0 && + (seconds_to_next == 0 || + ms_to_next > session->api_timeout)) { + time_t now = time (NULL); + elapsed_ms = (long)(1000*difftime(now, start_time)); + if (elapsed_ms > session->api_timeout) { + return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "API timeout expired"); + } + ms_to_next = (session->api_timeout - elapsed_ms); + has_timeout = 1; + } + else if (ms_to_next > 0) { + has_timeout = 1; + } + else + has_timeout = 0; + +#ifdef HAVE_POLL + { + struct pollfd sockets[1]; + + sockets[0].fd = session->socket_fd; + sockets[0].events = 0; + sockets[0].revents = 0; + + if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) + sockets[0].events |= POLLIN; + + if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) + sockets[0].events |= POLLOUT; + + rc = poll(sockets, 1, has_timeout?ms_to_next: -1); + } +#else + { + fd_set rfd; + fd_set wfd; + fd_set *writefd = NULL; + fd_set *readfd = NULL; + struct timeval tv; + + tv.tv_sec = ms_to_next / 1000; + tv.tv_usec = (ms_to_next - tv.tv_sec*1000) * 1000; + + if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) { + FD_ZERO(&rfd); + FD_SET(session->socket_fd, &rfd); + readfd = &rfd; + } + + if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) { + FD_ZERO(&wfd); + FD_SET(session->socket_fd, &wfd); + writefd = &wfd; + } + + rc = select(session->socket_fd + 1, readfd, writefd, NULL, + has_timeout ? &tv : NULL); + } +#endif + if(rc == 0) { + return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting on socket"); + } + if(rc < 0) { + return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Error waiting on socket"); + } + + return 0; /* ready to try again */ +} + +static int +session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock) +{ + int rc; + + if (session->startup_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "session_startup for socket %d", sock); + if (LIBSSH2_INVALID_SOCKET == sock) { + /* Did we forget something? */ + return _libssh2_error(session, LIBSSH2_ERROR_BAD_SOCKET, + "Bad socket provided"); + } + session->socket_fd = sock; + + session->socket_prev_blockstate = + !get_socket_nonblocking(session->socket_fd); + + if (session->socket_prev_blockstate) { + /* If in blocking state change to non-blocking */ + rc = session_nonblock(session->socket_fd, 1); + if (rc) { + return _libssh2_error(session, rc, + "Failed changing socket's " + "blocking state to non-blocking"); + } + } + + session->startup_state = libssh2_NB_state_created; + } + + if (session->startup_state == libssh2_NB_state_created) { + rc = banner_send(session); + if (rc) { + return _libssh2_error(session, rc, + "Failed sending banner"); + } + session->startup_state = libssh2_NB_state_sent; + session->banner_TxRx_state = libssh2_NB_state_idle; + } + + if (session->startup_state == libssh2_NB_state_sent) { + do { + rc = banner_receive(session); + if (rc) + return _libssh2_error(session, rc, + "Failed getting banner"); + } while(strncmp("SSH-", (char *)session->remote.banner, 4)); + + session->startup_state = libssh2_NB_state_sent1; + } + + if (session->startup_state == libssh2_NB_state_sent1) { + rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state); + if (rc) + return _libssh2_error(session, rc, + "Unable to exchange encryption keys"); + + session->startup_state = libssh2_NB_state_sent2; + } + + if (session->startup_state == libssh2_NB_state_sent2) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Requesting userauth service"); + + /* Request the userauth service */ + session->startup_service[0] = SSH_MSG_SERVICE_REQUEST; + _libssh2_htonu32(session->startup_service + 1, + sizeof("ssh-userauth") - 1); + memcpy(session->startup_service + 5, "ssh-userauth", + sizeof("ssh-userauth") - 1); + + session->startup_state = libssh2_NB_state_sent3; + } + + if (session->startup_state == libssh2_NB_state_sent3) { + rc = _libssh2_transport_send(session, session->startup_service, + sizeof("ssh-userauth") + 5 - 1, + NULL, 0); + if (rc) { + return _libssh2_error(session, rc, + "Unable to ask for ssh-userauth service"); + } + + session->startup_state = libssh2_NB_state_sent4; + } + + if (session->startup_state == libssh2_NB_state_sent4) { + rc = _libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT, + &session->startup_data, + &session->startup_data_len, 0, NULL, 0, + &session->startup_req_state); + if (rc) + return rc; + + session->startup_service_length = + _libssh2_ntohu32(session->startup_data + 1); + + if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) + || strncmp("ssh-userauth", (char *) session->startup_data + 5, + session->startup_service_length)) { + LIBSSH2_FREE(session, session->startup_data); + session->startup_data = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid response received from server"); + } + LIBSSH2_FREE(session, session->startup_data); + session->startup_data = NULL; + + session->startup_state = libssh2_NB_state_idle; + + return 0; + } + + /* just for safety return some error */ + return LIBSSH2_ERROR_INVAL; +} + +/* + * libssh2_session_handshake() + * + * session: LIBSSH2_SESSION struct allocated and owned by the calling program + * sock: *must* be populated with an opened and connected socket. + * + * Returns: 0 on success, or non-zero on failure + */ +LIBSSH2_API int +libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock) +{ + int rc; + + BLOCK_ADJUST(rc, session, session_startup(session, sock) ); + + return rc; +} + +/* + * libssh2_session_startup() + * + * DEPRECATED. Use libssh2_session_handshake() instead! This function is not + * portable enough. + * + * session: LIBSSH2_SESSION struct allocated and owned by the calling program + * sock: *must* be populated with an opened and connected socket. + * + * Returns: 0 on success, or non-zero on failure + */ +LIBSSH2_API int +libssh2_session_startup(LIBSSH2_SESSION *session, int sock) +{ + return libssh2_session_handshake(session, (libssh2_socket_t) sock); +} + +/* + * libssh2_session_free + * + * Frees the memory allocated to the session + * Also closes and frees any channels attached to this session + */ +static int +session_free(LIBSSH2_SESSION *session) +{ + int rc; + LIBSSH2_PACKET *pkg; + LIBSSH2_CHANNEL *ch; + LIBSSH2_LISTENER *l; + int packets_left = 0; + + if (session->free_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Freeing session resource", + session->remote.banner); + + session->free_state = libssh2_NB_state_created; + } + + if (session->free_state == libssh2_NB_state_created) { + while ((ch = _libssh2_list_first(&session->channels))) { + + rc = _libssh2_channel_free(ch); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + session->free_state = libssh2_NB_state_sent; + } + + if (session->free_state == libssh2_NB_state_sent) { + while ((l = _libssh2_list_first(&session->listeners))) { + rc = _libssh2_channel_forward_cancel(l); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + session->free_state = libssh2_NB_state_sent1; + } + + if (session->state & LIBSSH2_STATE_NEWKEYS) { + /* hostkey */ + if (session->hostkey && session->hostkey->dtor) { + session->hostkey->dtor(session, &session->server_hostkey_abstract); + } + + /* Client to Server */ + /* crypt */ + if (session->local.crypt && session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + /* comp */ + if (session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + /* mac */ + if (session->local.mac && session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + /* Server to Client */ + /* crypt */ + if (session->remote.crypt && session->remote.crypt->dtor) { + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + /* comp */ + if (session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + /* mac */ + if (session->remote.mac && session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + /* session_id */ + if (session->session_id) { + LIBSSH2_FREE(session, session->session_id); + } + } + + /* Free banner(s) */ + if (session->remote.banner) { + LIBSSH2_FREE(session, session->remote.banner); + } + if (session->local.banner) { + LIBSSH2_FREE(session, session->local.banner); + } + + /* Free preference(s) */ + if (session->kex_prefs) { + LIBSSH2_FREE(session, session->kex_prefs); + } + if (session->hostkey_prefs) { + LIBSSH2_FREE(session, session->hostkey_prefs); + } + + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + if (session->local.crypt_prefs) { + LIBSSH2_FREE(session, session->local.crypt_prefs); + } + if (session->local.mac_prefs) { + LIBSSH2_FREE(session, session->local.mac_prefs); + } + if (session->local.comp_prefs) { + LIBSSH2_FREE(session, session->local.comp_prefs); + } + if (session->local.lang_prefs) { + LIBSSH2_FREE(session, session->local.lang_prefs); + } + + if (session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + } + if (session->remote.crypt_prefs) { + LIBSSH2_FREE(session, session->remote.crypt_prefs); + } + if (session->remote.mac_prefs) { + LIBSSH2_FREE(session, session->remote.mac_prefs); + } + if (session->remote.comp_prefs) { + LIBSSH2_FREE(session, session->remote.comp_prefs); + } + if (session->remote.lang_prefs) { + LIBSSH2_FREE(session, session->remote.lang_prefs); + } + + /* + * Make sure all memory used in the state variables are free + */ + if (session->kexinit_data) { + LIBSSH2_FREE(session, session->kexinit_data); + } + if (session->startup_data) { + LIBSSH2_FREE(session, session->startup_data); + } + if (session->userauth_list_data) { + LIBSSH2_FREE(session, session->userauth_list_data); + } + if (session->userauth_pswd_data) { + LIBSSH2_FREE(session, session->userauth_pswd_data); + } + if (session->userauth_pswd_newpw) { + LIBSSH2_FREE(session, session->userauth_pswd_newpw); + } + if (session->userauth_host_packet) { + LIBSSH2_FREE(session, session->userauth_host_packet); + } + if (session->userauth_host_method) { + LIBSSH2_FREE(session, session->userauth_host_method); + } + if (session->userauth_host_data) { + LIBSSH2_FREE(session, session->userauth_host_data); + } + if (session->userauth_pblc_data) { + LIBSSH2_FREE(session, session->userauth_pblc_data); + } + if (session->userauth_pblc_packet) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + } + if (session->userauth_pblc_method) { + LIBSSH2_FREE(session, session->userauth_pblc_method); + } + if (session->userauth_kybd_data) { + LIBSSH2_FREE(session, session->userauth_kybd_data); + } + if (session->userauth_kybd_packet) { + LIBSSH2_FREE(session, session->userauth_kybd_packet); + } + if (session->userauth_kybd_auth_instruction) { + LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction); + } + if (session->open_packet) { + LIBSSH2_FREE(session, session->open_packet); + } + if (session->open_data) { + LIBSSH2_FREE(session, session->open_data); + } + if (session->direct_message) { + LIBSSH2_FREE(session, session->direct_message); + } + if (session->fwdLstn_packet) { + LIBSSH2_FREE(session, session->fwdLstn_packet); + } + if (session->pkeyInit_data) { + LIBSSH2_FREE(session, session->pkeyInit_data); + } + if (session->scpRecv_command) { + LIBSSH2_FREE(session, session->scpRecv_command); + } + if (session->scpSend_command) { + LIBSSH2_FREE(session, session->scpSend_command); + } + if (session->sftpInit_sftp) { + LIBSSH2_FREE(session, session->sftpInit_sftp); + } + + /* Free payload buffer */ + if (session->packet.total_num) { + LIBSSH2_FREE(session, session->packet.payload); + } + + /* Cleanup all remaining packets */ + while ((pkg = _libssh2_list_first(&session->packets))) { + packets_left++; + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "packet left with id %d", pkg->data[0]); + /* unlink the node */ + _libssh2_list_remove(&pkg->node); + + /* free */ + LIBSSH2_FREE(session, pkg->data); + LIBSSH2_FREE(session, pkg); + } + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Extra packets left %d", packets_left); + + if(session->socket_prev_blockstate) { + /* if the socket was previously blocking, put it back so */ + rc = session_nonblock(session->socket_fd, 0); + if (rc) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unable to reset socket's blocking state"); + } + } + + if (session->server_hostkey) { + LIBSSH2_FREE(session, session->server_hostkey); + } + + /* error string */ + if (session->err_msg && ((session->err_flags & LIBSSH2_ERR_FLAG_DUP) != 0)) { + LIBSSH2_FREE(session, (char *)session->err_msg); + } + + LIBSSH2_FREE(session, session); + + return 0; +} + +/* + * libssh2_session_free + * + * Frees the memory allocated to the session + * Also closes and frees any channels attached to this session + */ +LIBSSH2_API int +libssh2_session_free(LIBSSH2_SESSION * session) +{ + int rc; + + BLOCK_ADJUST(rc, session, session_free(session) ); + + return rc; +} + +/* + * libssh2_session_disconnect_ex + */ +static int +session_disconnect(LIBSSH2_SESSION *session, int reason, + const char *description, + const char *lang) +{ + unsigned char *s; + unsigned long descr_len = 0, lang_len = 0; + int rc; + + if (session->disconnect_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Disconnecting: reason=%d, desc=%s, lang=%s", reason, + description, lang); + if (description) + descr_len = strlen(description); + + if (lang) + lang_len = strlen(lang); + + if(descr_len > 256) + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "too long description"); + + /* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */ + session->disconnect_data_len = descr_len + lang_len + 13; + + s = session->disconnect_data; + + *(s++) = SSH_MSG_DISCONNECT; + _libssh2_store_u32(&s, reason); + _libssh2_store_str(&s, description, descr_len); + /* store length only, lang is sent separately */ + _libssh2_store_u32(&s, lang_len); + + session->disconnect_state = libssh2_NB_state_created; + } + + rc = _libssh2_transport_send(session, session->disconnect_data, + session->disconnect_data_len, + (unsigned char *)lang, lang_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + session->disconnect_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_session_disconnect_ex + */ +LIBSSH2_API int +libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, + const char *desc, const char *lang) +{ + int rc; + + BLOCK_ADJUST(rc, session, + session_disconnect(session, reason, desc, lang)); + + return rc; +} + +/* libssh2_session_methods + * + * Return the currently active methods for method_type + * + * NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string + * regardless of actual negotiation Strings should NOT be freed + */ +LIBSSH2_API const char * +libssh2_session_methods(LIBSSH2_SESSION * session, int method_type) +{ + /* All methods have char *name as their first element */ + const LIBSSH2_KEX_METHOD *method = NULL; + + switch (method_type) { + case LIBSSH2_METHOD_KEX: + method = session->kex; + break; + + case LIBSSH2_METHOD_HOSTKEY: + method = (LIBSSH2_KEX_METHOD *) session->hostkey; + break; + + case LIBSSH2_METHOD_CRYPT_CS: + method = (LIBSSH2_KEX_METHOD *) session->local.crypt; + break; + + case LIBSSH2_METHOD_CRYPT_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.crypt; + break; + + case LIBSSH2_METHOD_MAC_CS: + method = (LIBSSH2_KEX_METHOD *) session->local.mac; + break; + + case LIBSSH2_METHOD_MAC_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.mac; + break; + + case LIBSSH2_METHOD_COMP_CS: + method = (LIBSSH2_KEX_METHOD *) session->local.comp; + break; + + case LIBSSH2_METHOD_COMP_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.comp; + break; + + case LIBSSH2_METHOD_LANG_CS: + return ""; + + case LIBSSH2_METHOD_LANG_SC: + return ""; + + default: + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "Invalid parameter specified for method_type"); + return NULL; + } + + if (!method) { + _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No method negotiated"); + return NULL; + } + + return method->name; +} + +/* libssh2_session_abstract + * Retrieve a pointer to the abstract property + */ +LIBSSH2_API void ** +libssh2_session_abstract(LIBSSH2_SESSION * session) +{ + return &session->abstract; +} + +/* libssh2_session_last_error + * + * Returns error code and populates an error string into errmsg If want_buf is + * non-zero then the string placed into errmsg must be freed by the calling + * program. Otherwise it is assumed to be owned by libssh2 + */ +LIBSSH2_API int +libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg, + int *errmsg_len, int want_buf) +{ + size_t msglen = 0; + + /* No error to report */ + if (!session->err_code) { + if (errmsg) { + if (want_buf) { + *errmsg = LIBSSH2_ALLOC(session, 1); + if (*errmsg) { + **errmsg = 0; + } + } else { + *errmsg = (char *) ""; + } + } + if (errmsg_len) { + *errmsg_len = 0; + } + return 0; + } + + if (errmsg) { + const char *error = session->err_msg ? session->err_msg : ""; + + msglen = strlen(error); + + if (want_buf) { + /* Make a copy so the calling program can own it */ + *errmsg = LIBSSH2_ALLOC(session, msglen + 1); + if (*errmsg) { + memcpy(*errmsg, error, msglen); + (*errmsg)[msglen] = 0; + } + } + else + *errmsg = (char *)error; + } + + if (errmsg_len) { + *errmsg_len = msglen; + } + + return session->err_code; +} + +/* libssh2_session_last_errno + * + * Returns error code + */ +LIBSSH2_API int +libssh2_session_last_errno(LIBSSH2_SESSION * session) +{ + return session->err_code; +} + +/* libssh2_session_set_last_error + * + * Sets the internal error code for the session. + * + * This function is available specifically to be used by high level + * language wrappers (i.e. Python or Perl) that may extend the library + * features while still relying on its error reporting mechanism. + */ +LIBSSH2_API int +libssh2_session_set_last_error(LIBSSH2_SESSION* session, + int errcode, + const char* errmsg) +{ + return _libssh2_error_flags(session, errcode, errmsg, + LIBSSH2_ERR_FLAG_DUP); +} + +/* Libssh2_session_flag + * + * Set/Get session flags + * + * Return error code. + */ +LIBSSH2_API int +libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value) +{ + switch(flag) { + case LIBSSH2_FLAG_SIGPIPE: + session->flag.sigpipe = value; + break; + case LIBSSH2_FLAG_COMPRESS: + session->flag.compress = value; + break; + default: + /* unknown flag */ + return LIBSSH2_ERROR_INVAL; + } + + return LIBSSH2_ERROR_NONE; +} + +/* _libssh2_session_set_blocking + * + * Set a session's blocking mode on or off, return the previous status when + * this function is called. Note this function does not alter the state of the + * actual socket involved. + */ +int +_libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) +{ + int bl = session->api_block_mode; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Setting blocking mode %s", blocking?"ON":"OFF"); + session->api_block_mode = blocking; + + return bl; +} + +/* libssh2_session_set_blocking + * + * Set a channel's blocking mode on or off, similar to a socket's + * fcntl(fd, F_SETFL, O_NONBLOCK); type command + */ +LIBSSH2_API void +libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking) +{ + (void) _libssh2_session_set_blocking(session, blocking); +} + +/* libssh2_session_get_blocking + * + * Returns a session's blocking mode on or off + */ +LIBSSH2_API int +libssh2_session_get_blocking(LIBSSH2_SESSION * session) +{ + return session->api_block_mode; +} + + +/* libssh2_session_set_timeout + * + * Set a session's timeout (in msec) for blocking mode, + * or 0 to disable timeouts. + */ +LIBSSH2_API void +libssh2_session_set_timeout(LIBSSH2_SESSION * session, long timeout) +{ + session->api_timeout = timeout; +} + +/* libssh2_session_get_timeout + * + * Returns a session's timeout, or 0 if disabled + */ +LIBSSH2_API long +libssh2_session_get_timeout(LIBSSH2_SESSION * session) +{ + return session->api_timeout; +} + +/* + * libssh2_poll_channel_read + * + * Returns 0 if no data is waiting on channel, + * non-0 if data is available + */ +LIBSSH2_API int +libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended) +{ + LIBSSH2_SESSION *session; + LIBSSH2_PACKET *packet; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + session = channel->session; + packet = _libssh2_list_first(&session->packets); + + while (packet) { + if ( channel->local.id == _libssh2_ntohu32(packet->data + 1)) { + if ( extended == 1 && + (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA + || packet->data[0] == SSH_MSG_CHANNEL_DATA )) { + return 1; + } else if ( extended == 0 && + packet->data[0] == SSH_MSG_CHANNEL_DATA) { + return 1; + } + /* else - no data of any type is ready to be read */ + } + packet = _libssh2_list_next(&packet->node); + } + + return 0; +} + +/* + * poll_channel_write + * + * Returns 0 if writing to channel would block, + * non-0 if data can be written without blocking + */ +static inline int +poll_channel_write(LIBSSH2_CHANNEL * channel) +{ + return channel->local.window_size ? 1 : 0; +} + +/* poll_listener_queued + * + * Returns 0 if no connections are waiting to be accepted + * non-0 if one or more connections are available + */ +static inline int +poll_listener_queued(LIBSSH2_LISTENER * listener) +{ + return _libssh2_list_first(&listener->queue) ? 1 : 0; +} + +/* + * libssh2_poll + * + * Poll sockets, channels, and listeners for activity + */ +LIBSSH2_API int +libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout) +{ + long timeout_remaining; + unsigned int i, active_fds; +#ifdef HAVE_POLL + LIBSSH2_SESSION *session = NULL; +#ifdef HAVE_ALLOCA + struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds); +#else + struct pollfd sockets[256]; + + if (nfds > 256) + /* systems without alloca use a fixed-size array, this can be fixed if + we really want to, at least if the compiler is a C99 capable one */ + return -1; +#endif + /* Setup sockets for polling */ + for(i = 0; i < nfds; i++) { + fds[i].revents = 0; + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + sockets[i].fd = fds[i].fd.socket; + sockets[i].events = fds[i].events; + sockets[i].revents = 0; + break; + + case LIBSSH2_POLLFD_CHANNEL: + sockets[i].fd = fds[i].fd.channel->session->socket_fd; + sockets[i].events = POLLIN; + sockets[i].revents = 0; + if (!session) + session = fds[i].fd.channel->session; + break; + + case LIBSSH2_POLLFD_LISTENER: + sockets[i].fd = fds[i].fd.listener->session->socket_fd; + sockets[i].events = POLLIN; + sockets[i].revents = 0; + if (!session) + session = fds[i].fd.listener->session; + break; + + default: + if (session) + _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, + "Invalid descriptor passed to libssh2_poll()"); + return -1; + } + } +#elif defined(HAVE_SELECT) + LIBSSH2_SESSION *session = NULL; + libssh2_socket_t maxfd = 0; + fd_set rfds, wfds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + for(i = 0; i < nfds; i++) { + fds[i].revents = 0; + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + if (fds[i].events & LIBSSH2_POLLFD_POLLIN) { + FD_SET(fds[i].fd.socket, &rfds); + if (fds[i].fd.socket > maxfd) + maxfd = fds[i].fd.socket; + } + if (fds[i].events & LIBSSH2_POLLFD_POLLOUT) { + FD_SET(fds[i].fd.socket, &wfds); + if (fds[i].fd.socket > maxfd) + maxfd = fds[i].fd.socket; + } + break; + + case LIBSSH2_POLLFD_CHANNEL: + FD_SET(fds[i].fd.channel->session->socket_fd, &rfds); + if (fds[i].fd.channel->session->socket_fd > maxfd) + maxfd = fds[i].fd.channel->session->socket_fd; + if (!session) + session = fds[i].fd.channel->session; + break; + + case LIBSSH2_POLLFD_LISTENER: + FD_SET(fds[i].fd.listener->session->socket_fd, &rfds); + if (fds[i].fd.listener->session->socket_fd > maxfd) + maxfd = fds[i].fd.listener->session->socket_fd; + if (!session) + session = fds[i].fd.listener->session; + break; + + default: + if (session) + _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, + "Invalid descriptor passed to libssh2_poll()"); + return -1; + } + } +#else + /* No select() or poll() + * no sockets structure to setup + */ + + timeout = 0; +#endif /* HAVE_POLL or HAVE_SELECT */ + + timeout_remaining = timeout; + do { +#if defined(HAVE_POLL) || defined(HAVE_SELECT) + int sysret; +#endif + + active_fds = 0; + + for(i = 0; i < nfds; i++) { + if (fds[i].events != fds[i].revents) { + switch (fds[i].type) { + case LIBSSH2_POLLFD_CHANNEL: + if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && + /* Want to be ready for read */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { + /* Not yet known to be ready for read */ + fds[i].revents |= + libssh2_poll_channel_read(fds[i].fd.channel, + 0) ? + LIBSSH2_POLLFD_POLLIN : 0; + } + if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) && + /* Want to be ready for extended read */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) { + /* Not yet known to be ready for extended read */ + fds[i].revents |= + libssh2_poll_channel_read(fds[i].fd.channel, + 1) ? + LIBSSH2_POLLFD_POLLEXT : 0; + } + if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) && + /* Want to be ready for write */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { + /* Not yet known to be ready for write */ + fds[i].revents |= + poll_channel_write(fds[i].fd. channel) ? + LIBSSH2_POLLFD_POLLOUT : 0; + } + if (fds[i].fd.channel->remote.close + || fds[i].fd.channel->local.close) { + fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED; + } + if (fds[i].fd.channel->session->socket_state == + LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= + LIBSSH2_POLLFD_CHANNEL_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + break; + + case LIBSSH2_POLLFD_LISTENER: + if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && + /* Want a connection */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { + /* No connections known of yet */ + fds[i].revents |= + poll_listener_queued(fds[i].fd. listener) ? + LIBSSH2_POLLFD_POLLIN : 0; + } + if (fds[i].fd.listener->session->socket_state == + LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= + LIBSSH2_POLLFD_LISTENER_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + break; + } + } + if (fds[i].revents) { + active_fds++; + } + } + + if (active_fds) { + /* Don't block on the sockets if we have channels/listeners which + are ready */ + timeout_remaining = 0; + } +#ifdef HAVE_POLL + +#ifdef HAVE_LIBSSH2_GETTIMEOFDAY + { + struct timeval tv_begin, tv_end; + + _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL); + sysret = poll(sockets, nfds, timeout_remaining); + _libssh2_gettimeofday((struct timeval *) &tv_end, NULL); + timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; + timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; + } +#else + /* If the platform doesn't support gettimeofday, + * then just make the call non-blocking and walk away + */ + sysret = poll(sockets, nfds, timeout_remaining); + timeout_remaining = 0; +#endif /* HAVE_GETTIMEOFDAY */ + + if (sysret > 0) { + for(i = 0; i < nfds; i++) { + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + fds[i].revents = sockets[i].revents; + sockets[i].revents = 0; /* In case we loop again, be nice */ + if (fds[i].revents) { + active_fds++; + } + break; + case LIBSSH2_POLLFD_CHANNEL: + if (sockets[i].events & POLLIN) { + /* Spin session until no data available */ + while (_libssh2_transport_read(fds[i].fd.channel->session) + > 0); + } + if (sockets[i].revents & POLLHUP) { + fds[i].revents |= + LIBSSH2_POLLFD_CHANNEL_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + sockets[i].revents = 0; + break; + case LIBSSH2_POLLFD_LISTENER: + if (sockets[i].events & POLLIN) { + /* Spin session until no data available */ + while (_libssh2_transport_read(fds[i].fd.listener->session) + > 0); + } + if (sockets[i].revents & POLLHUP) { + fds[i].revents |= + LIBSSH2_POLLFD_LISTENER_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + sockets[i].revents = 0; + break; + } + } + } +#elif defined(HAVE_SELECT) + tv.tv_sec = timeout_remaining / 1000; + tv.tv_usec = (timeout_remaining % 1000) * 1000; +#ifdef HAVE_LIBSSH2_GETTIMEOFDAY + { + struct timeval tv_begin, tv_end; + + _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL); + sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv); + _libssh2_gettimeofday((struct timeval *) &tv_end, NULL); + + timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; + timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; + } +#else + /* If the platform doesn't support gettimeofday, + * then just make the call non-blocking and walk away + */ + sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv); + timeout_remaining = 0; +#endif + + if (sysret > 0) { + for(i = 0; i < nfds; i++) { + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + if (FD_ISSET(fds[i].fd.socket, &rfds)) { + fds[i].revents |= LIBSSH2_POLLFD_POLLIN; + } + if (FD_ISSET(fds[i].fd.socket, &wfds)) { + fds[i].revents |= LIBSSH2_POLLFD_POLLOUT; + } + if (fds[i].revents) { + active_fds++; + } + break; + + case LIBSSH2_POLLFD_CHANNEL: + if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) { + /* Spin session until no data available */ + while (_libssh2_transport_read(fds[i].fd.channel->session) + > 0); + } + break; + + case LIBSSH2_POLLFD_LISTENER: + if (FD_ISSET + (fds[i].fd.listener->session->socket_fd, &rfds)) { + /* Spin session until no data available */ + while (_libssh2_transport_read(fds[i].fd.listener->session) + > 0); + } + break; + } + } + } +#endif /* else no select() or poll() -- timeout (and by extension + * timeout_remaining) will be equal to 0 */ + } while ((timeout_remaining > 0) && !active_fds); + + return active_fds; +} + +/* + * libssh2_session_block_directions + * + * Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN + * Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked + * or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked + */ +LIBSSH2_API int +libssh2_session_block_directions(LIBSSH2_SESSION *session) +{ + return session->socket_block_directions; +} + +/* libssh2_session_banner_get + * Get the remote banner (server ID string) + */ + +LIBSSH2_API const char * +libssh2_session_banner_get(LIBSSH2_SESSION *session) +{ + /* to avoid a coredump when session is NULL */ + if (NULL == session) + return NULL; + + if (NULL==session->remote.banner) + return NULL; + + return (const char *) session->remote.banner; +} diff --git a/libssh2/src/session.h b/libssh2/src/session.h new file mode 100644 index 000000000..aff4f2c5c --- /dev/null +++ b/libssh2/src/session.h @@ -0,0 +1,93 @@ +#ifndef LIBSSH2_SESSION_H +#define LIBSSH2_SESSION_H +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2009-2010 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +/* Conveniance-macros to allow code like this; + + int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) ); + + int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) ); + + The point of course being to make sure that while in non-blocking mode + these always return no matter what the return code is, but in blocking mode + it blocks if EAGAIN is the reason for the return from the underlying + function. + +*/ +#define BLOCK_ADJUST(rc,sess,x) \ + do { \ + time_t entry_time = time (NULL); \ + do { \ + rc = x; \ + /* the order of the check below is important to properly deal with \ + the case when the 'sess' is freed */ \ + if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \ + break; \ + rc = _libssh2_wait_socket(sess, entry_time); \ + } while(!rc); \ + } while(0) + +/* + * For functions that returns a pointer, we need to check if the API is + * non-blocking and return immediately. If the pointer is non-NULL we return + * immediately. If the API is blocking and we get a NULL we check the errno + * and *only* if that is EAGAIN we loop and wait for socket action. + */ +#define BLOCK_ADJUST_ERRNO(ptr,sess,x) \ + do { \ + time_t entry_time = time (NULL); \ + int rc; \ + do { \ + ptr = x; \ + if(!sess->api_block_mode || \ + (ptr != NULL) || \ + (libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \ + break; \ + rc = _libssh2_wait_socket(sess, entry_time); \ + } while(!rc); \ + } while(0) + + +int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time); + +/* this is the lib-internal set blocking function */ +int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking); + +#endif /* LIBSSH2_SESSION_H */ diff --git a/libssh2/src/sftp.c b/libssh2/src/sftp.c new file mode 100644 index 000000000..7c4411640 --- /dev/null +++ b/libssh2/src/sftp.c @@ -0,0 +1,3466 @@ +/* Copyright (c) 2004-2008, Sara Golemon + * Copyright (c) 2007 Eli Fant + * Copyright (c) 2009-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include + +#include "libssh2_priv.h" +#include "libssh2_sftp.h" +#include "channel.h" +#include "session.h" +#include "sftp.h" + +/* Note: Version 6 was documented at the time of writing + * However it was marked as "DO NOT IMPLEMENT" due to pending changes + * + * This release of libssh2 implements Version 5 with automatic downgrade + * based on server's declaration + */ + +/* SFTP packet types */ +#define SSH_FXP_INIT 1 +#define SSH_FXP_VERSION 2 +#define SSH_FXP_OPEN 3 +#define SSH_FXP_CLOSE 4 +#define SSH_FXP_READ 5 +#define SSH_FXP_WRITE 6 +#define SSH_FXP_LSTAT 7 +#define SSH_FXP_FSTAT 8 +#define SSH_FXP_SETSTAT 9 +#define SSH_FXP_FSETSTAT 10 +#define SSH_FXP_OPENDIR 11 +#define SSH_FXP_READDIR 12 +#define SSH_FXP_REMOVE 13 +#define SSH_FXP_MKDIR 14 +#define SSH_FXP_RMDIR 15 +#define SSH_FXP_REALPATH 16 +#define SSH_FXP_STAT 17 +#define SSH_FXP_RENAME 18 +#define SSH_FXP_READLINK 19 +#define SSH_FXP_SYMLINK 20 +#define SSH_FXP_STATUS 101 +#define SSH_FXP_HANDLE 102 +#define SSH_FXP_DATA 103 +#define SSH_FXP_NAME 104 +#define SSH_FXP_ATTRS 105 +#define SSH_FXP_EXTENDED 200 +#define SSH_FXP_EXTENDED_REPLY 201 + +/* S_IFREG */ +#define LIBSSH2_SFTP_ATTR_PFILETYPE_FILE 0100000 +/* S_IFDIR */ +#define LIBSSH2_SFTP_ATTR_PFILETYPE_DIR 0040000 + +#define SSH_FXE_STATVFS_ST_RDONLY 0x00000001 +#define SSH_FXE_STATVFS_ST_NOSUID 0x00000002 + +/* This is the maximum packet length to accept, as larger than this indicate + some kind of server problem. */ +#define LIBSSH2_SFTP_PACKET_MAXLEN 80000 + +static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, + uint32_t request_id, unsigned char **data, + size_t *data_len); +static void sftp_packet_flush(LIBSSH2_SFTP *sftp); + +/* sftp_attrsize + * Size that attr with this flagset will occupy when turned into a bin struct + */ +static int sftp_attrsize(unsigned long flags) +{ + return (4 + /* flags(4) */ + ((flags & LIBSSH2_SFTP_ATTR_SIZE) ? 8 : 0) + + ((flags & LIBSSH2_SFTP_ATTR_UIDGID) ? 8 : 0) + + ((flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) ? 4 : 0) + + ((flags & LIBSSH2_SFTP_ATTR_ACMODTIME) ? 8 : 0)); + /* atime + mtime as u32 */ +} + +/* _libssh2_store_u64 + */ +static void _libssh2_store_u64(unsigned char **ptr, libssh2_uint64_t value) +{ + uint32_t msl = (uint32_t)(value >> 32); + unsigned char *buf = *ptr; + + buf[0] = (unsigned char)((msl >> 24) & 0xFF); + buf[1] = (unsigned char)((msl >> 16) & 0xFF); + buf[2] = (unsigned char)((msl >> 8) & 0xFF); + buf[3] = (unsigned char)( msl & 0xFF); + + buf[4] = (unsigned char)((value >> 24) & 0xFF); + buf[5] = (unsigned char)((value >> 16) & 0xFF); + buf[6] = (unsigned char)((value >> 8) & 0xFF); + buf[7] = (unsigned char)( value & 0xFF); + + *ptr += 8; +} + +/* + * Search list of zombied FXP_READ request IDs. + * + * Returns NULL if ID not in list. + */ +static struct sftp_zombie_requests * +find_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) +{ + struct sftp_zombie_requests *zombie = + _libssh2_list_first(&sftp->zombie_requests); + + while(zombie) { + if(zombie->request_id == request_id) + break; + else + zombie = _libssh2_list_next(&zombie->node); + } + + return zombie; +} + +static void +remove_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + + struct sftp_zombie_requests *zombie = find_zombie_request(sftp, + request_id); + if(zombie) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Removing request ID %ld from the list of zombie requests", + request_id); + + _libssh2_list_remove(&zombie->node); + LIBSSH2_FREE(session, zombie); + } +} + +static int +add_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + + struct sftp_zombie_requests *zombie; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Marking request ID %ld as a zombie request", request_id); + + zombie = LIBSSH2_ALLOC(sftp->channel->session, + sizeof(struct sftp_zombie_requests)); + if (!zombie) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "malloc fail for zombie request ID"); + else { + zombie->request_id = request_id; + _libssh2_list_add(&sftp->zombie_requests, &zombie->node); + return LIBSSH2_ERROR_NONE; + } +} + +/* + * sftp_packet_add + * + * Add a packet to the SFTP packet brigade + */ +static int +sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data, + size_t data_len) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + LIBSSH2_SFTP_PACKET *packet; + uint32_t request_id; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Received packet type %d (len %d)", + (int) data[0], data_len); + + /* + * Experience shows that if we mess up EAGAIN handling somewhere or + * otherwise get out of sync with the channel, this is where we first get + * a wrong byte and if so we need to bail out at once to aid tracking the + * problem better. + */ + + switch(data[0]) { + case SSH_FXP_INIT: + case SSH_FXP_VERSION: + case SSH_FXP_OPEN: + case SSH_FXP_CLOSE: + case SSH_FXP_READ: + case SSH_FXP_WRITE: + case SSH_FXP_LSTAT: + case SSH_FXP_FSTAT: + case SSH_FXP_SETSTAT: + case SSH_FXP_FSETSTAT: + case SSH_FXP_OPENDIR: + case SSH_FXP_READDIR: + case SSH_FXP_REMOVE: + case SSH_FXP_MKDIR: + case SSH_FXP_RMDIR: + case SSH_FXP_REALPATH: + case SSH_FXP_STAT: + case SSH_FXP_RENAME: + case SSH_FXP_READLINK: + case SSH_FXP_SYMLINK: + case SSH_FXP_STATUS: + case SSH_FXP_HANDLE: + case SSH_FXP_DATA: + case SSH_FXP_NAME: + case SSH_FXP_ATTRS: + case SSH_FXP_EXTENDED: + case SSH_FXP_EXTENDED_REPLY: + break; + default: + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Out of sync with the world"); + } + + request_id = _libssh2_ntohu32(&data[1]); + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet id %d", + request_id); + + /* Don't add the packet if it answers a request we've given up on. */ + if((data[0] == SSH_FXP_STATUS || data[0] == SSH_FXP_DATA) + && find_zombie_request(sftp, request_id)) { + + /* If we get here, the file ended before the response arrived. We + are no longer interested in the request so we discard it */ + + LIBSSH2_FREE(session, data); + + remove_zombie_request(sftp, request_id); + return LIBSSH2_ERROR_NONE; + } + + packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_PACKET)); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate datablock for SFTP packet"); + } + + packet->data = data; + packet->data_len = data_len; + packet->request_id = request_id; + + _libssh2_list_add(&sftp->packets, &packet->node); + + return LIBSSH2_ERROR_NONE; +} + +/* + * sftp_packet_read + * + * Frame an SFTP packet off the channel + */ +static int +sftp_packet_read(LIBSSH2_SFTP *sftp) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned char *packet = NULL; + ssize_t rc; + unsigned long recv_window; + int packet_type; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "recv packet"); + + switch(sftp->packet_state) { + case libssh2_NB_state_sent: /* EAGAIN from window adjusting */ + sftp->packet_state = libssh2_NB_state_idle; + + packet = sftp->partial_packet; + goto window_adjust; + + case libssh2_NB_state_sent1: /* EAGAIN from channel read */ + sftp->packet_state = libssh2_NB_state_idle; + + packet = sftp->partial_packet; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "partial read cont, len: %lu", sftp->partial_len); + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "partial read cont, already recvd: %lu", + sftp->partial_received); + /* fall-through */ + default: + if(!packet) { + /* only do this if there's not already a packet buffer allocated + to use */ + + /* each packet starts with a 32 bit length field */ + rc = _libssh2_channel_read(channel, 0, + (char *)&sftp->partial_size[ + sftp->partial_size_len], + 4 - sftp->partial_size_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (rc < 0) + return _libssh2_error(session, rc, "channel read"); + + sftp->partial_size_len += rc; + + if(4 != sftp->partial_size_len) + /* we got a short read for the length part */ + return LIBSSH2_ERROR_EAGAIN; + + sftp->partial_len = _libssh2_ntohu32(sftp->partial_size); + /* make sure we don't proceed if the packet size is unreasonably + large */ + if (sftp->partial_len > LIBSSH2_SFTP_PACKET_MAXLEN) + return _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, + "SFTP packet too large"); + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Data begin - Packet Length: %lu", + sftp->partial_len); + packet = LIBSSH2_ALLOC(session, sftp->partial_len); + if (!packet) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate SFTP packet"); + sftp->partial_size_len = 0; + sftp->partial_received = 0; /* how much of the packet already + received */ + sftp->partial_packet = packet; + + window_adjust: + recv_window = libssh2_channel_window_read_ex(channel, NULL, NULL); + + if(sftp->partial_len > recv_window) { + /* ask for twice the data amount we need at once */ + rc = _libssh2_channel_receive_window_adjust(channel, + sftp->partial_len*2, + 1, NULL); + /* store the state so that we continue with the correct + operation at next invoke */ + sftp->packet_state = (rc == LIBSSH2_ERROR_EAGAIN)? + libssh2_NB_state_sent: + libssh2_NB_state_idle; + + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + } + + /* Read as much of the packet as we can */ + while (sftp->partial_len > sftp->partial_received) { + rc = _libssh2_channel_read(channel, 0, + (char *)&packet[sftp->partial_received], + sftp->partial_len - + sftp->partial_received); + + if (rc == LIBSSH2_ERROR_EAGAIN) { + /* + * We received EAGAIN, save what we have and return EAGAIN to + * the caller. Set 'partial_packet' so that this function + * knows how to continue on the next invoke. + */ + sftp->packet_state = libssh2_NB_state_sent1; + return rc; + } + else if (rc < 0) { + LIBSSH2_FREE(session, packet); + sftp->partial_packet = NULL; + return _libssh2_error(session, rc, + "Error waiting for SFTP packet"); + } + sftp->partial_received += rc; + } + + sftp->partial_packet = NULL; + + /* sftp_packet_add takes ownership of the packet and might free it + so we take a copy of the packet type before we call it. */ + packet_type = packet[0]; + rc = sftp_packet_add(sftp, packet, sftp->partial_len); + if (rc) { + LIBSSH2_FREE(session, packet); + return rc; + } + else { + return packet_type; + } + } + /* WON'T REACH */ +} +/* + * sftp_packetlist_flush + * + * Remove all pending packets in the packet_list and the corresponding one(s) + * in the SFTP packet brigade. + */ +static void sftp_packetlist_flush(LIBSSH2_SFTP_HANDLE *handle) +{ + struct sftp_pipeline_chunk *chunk; + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_SESSION *session = sftp->channel->session; + + /* remove pending packets, if any */ + chunk = _libssh2_list_first(&handle->packet_list); + while(chunk) { + unsigned char *data; + size_t data_len; + int rc; + struct sftp_pipeline_chunk *next = _libssh2_list_next(&chunk->node); + + rc = sftp_packet_ask(sftp, SSH_FXP_STATUS, + chunk->request_id, &data, &data_len); + if(rc) + rc = sftp_packet_ask(sftp, SSH_FXP_DATA, + chunk->request_id, &data, &data_len); + + if(!rc) + /* we found a packet, free it */ + LIBSSH2_FREE(session, data); + else if(chunk->sent) + /* there was no incoming packet for this request, mark this + request as a zombie if it ever sent the request */ + add_zombie_request(sftp, chunk->request_id); + + _libssh2_list_remove(&chunk->node); + LIBSSH2_FREE(session, chunk); + chunk = next; + } +} + + +/* + * sftp_packet_ask() + * + * Checks if there's a matching SFTP packet available. + */ +static int +sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, + uint32_t request_id, unsigned char **data, + size_t *data_len) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets); + + if(!packet) + return -1; + + /* Special consideration when getting VERSION packet */ + + while (packet) { + if((packet->data[0] == packet_type) && + ((packet_type == SSH_FXP_VERSION) || + (packet->request_id == request_id))) { + + /* Match! Fetch the data */ + *data = packet->data; + *data_len = packet->data_len; + + /* unlink and free this struct */ + _libssh2_list_remove(&packet->node); + LIBSSH2_FREE(session, packet); + + return 0; + } + /* check next struct in the list */ + packet = _libssh2_list_next(&packet->node); + } + return -1; +} + +/* sftp_packet_require + * A la libssh2_packet_require + */ +static int +sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type, + uint32_t request_id, unsigned char **data, + size_t *data_len) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + int rc; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Requiring packet %d id %ld", + (int) packet_type, request_id); + + if (sftp_packet_ask(sftp, packet_type, request_id, data, data_len) == 0) { + /* The right packet was available in the packet brigade */ + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d", + (int) packet_type); + return LIBSSH2_ERROR_NONE; + } + + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + rc = sftp_packet_read(sftp); + if (rc < 0) + return rc; + + /* data was read, check the queue again */ + if (!sftp_packet_ask(sftp, packet_type, request_id, data, data_len)) { + /* The right packet was available in the packet brigade */ + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d", + (int) packet_type); + return LIBSSH2_ERROR_NONE; + } + } + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* sftp_packet_requirev + * Require one of N possible responses + */ +static int +sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses, + const unsigned char *valid_responses, + uint32_t request_id, unsigned char **data, + size_t *data_len) +{ + int i; + int rc; + + /* If no timeout is active, start a new one */ + if (sftp->requirev_start == 0) + sftp->requirev_start = time(NULL); + + while (sftp->channel->session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + for(i = 0; i < num_valid_responses; i++) { + if (sftp_packet_ask(sftp, valid_responses[i], request_id, + data, data_len) == 0) { + /* + * Set to zero before all returns to say + * the timeout is not active + */ + sftp->requirev_start = 0; + return LIBSSH2_ERROR_NONE; + } + } + + rc = sftp_packet_read(sftp); + if ((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) { + sftp->requirev_start = 0; + return rc; + } else if (rc <= 0) { + /* prevent busy-looping */ + long left = + LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - sftp->requirev_start); + + if (left <= 0) { + sftp->requirev_start = 0; + return LIBSSH2_ERROR_TIMEOUT; + } + else if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + } + } + + sftp->requirev_start = 0; + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* sftp_attr2bin + * Populate attributes into an SFTP block + */ +static ssize_t +sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES * attrs) +{ + unsigned char *s = p; + uint32_t flag_mask = + LIBSSH2_SFTP_ATTR_SIZE | LIBSSH2_SFTP_ATTR_UIDGID | + LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME; + + /* TODO: When we add SFTP4+ functionality flag_mask can get additional + bits */ + + if (!attrs) { + _libssh2_htonu32(s, 0); + return 4; + } + + _libssh2_store_u32(&s, attrs->flags & flag_mask); + + if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { + _libssh2_store_u64(&s, attrs->filesize); + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { + _libssh2_store_u32(&s, attrs->uid); + _libssh2_store_u32(&s, attrs->gid); + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { + _libssh2_store_u32(&s, attrs->permissions); + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { + _libssh2_store_u32(&s, attrs->atime); + _libssh2_store_u32(&s, attrs->mtime); + } + + return (s - p); +} + +/* sftp_bin2attr + */ +static int +sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p) +{ + const unsigned char *s = p; + + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + attrs->flags = _libssh2_ntohu32(s); + s += 4; + + if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { + attrs->filesize = _libssh2_ntohu64(s); + s += 8; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { + attrs->uid = _libssh2_ntohu32(s); + s += 4; + attrs->gid = _libssh2_ntohu32(s); + s += 4; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { + attrs->permissions = _libssh2_ntohu32(s); + s += 4; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { + attrs->atime = _libssh2_ntohu32(s); + s += 4; + attrs->mtime = _libssh2_ntohu32(s); + s += 4; + } + + return (s - p); +} + +/* ************ + * SFTP API * + ************ */ + +LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor); + +/* libssh2_sftp_dtor + * Shutdown an SFTP stream when the channel closes + */ +LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor) +{ + LIBSSH2_SFTP *sftp = (LIBSSH2_SFTP *) (*channel_abstract); + + (void) session_abstract; + (void) channel; + + /* Free the partial packet storage for sftp_packet_read */ + if (sftp->partial_packet) { + LIBSSH2_FREE(session, sftp->partial_packet); + } + + /* Free the packet storage for _libssh2_sftp_packet_readdir */ + if (sftp->readdir_packet) { + LIBSSH2_FREE(session, sftp->readdir_packet); + } + + LIBSSH2_FREE(session, sftp); +} + +/* + * sftp_init + * + * Startup an SFTP session + */ +static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session) +{ + unsigned char *data, *s; + size_t data_len; + ssize_t rc; + LIBSSH2_SFTP *sftp_handle; + + if (session->sftpInit_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Initializing SFTP subsystem"); + + /* + * The 'sftpInit_sftp' and 'sftpInit_channel' struct fields within the + * session struct are only to be used during the setup phase. As soon + * as the SFTP session is created they are cleared and can thus be + * re-used again to allow any amount of SFTP handles per sessions. + * + * Note that you MUST NOT try to call libssh2_sftp_init() again to get + * another handle until the previous call has finished and either + * successfully made a handle or failed and returned error (not + * including *EAGAIN). + */ + + assert(session->sftpInit_sftp == NULL); + session->sftpInit_sftp = NULL; + session->sftpInit_state = libssh2_NB_state_created; + } + + sftp_handle = session->sftpInit_sftp; + + if (session->sftpInit_state == libssh2_NB_state_created) { + session->sftpInit_channel = + _libssh2_channel_open(session, "session", sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); + if (!session->sftpInit_channel) { + if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel"); + } + else { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to startup channel"); + session->sftpInit_state = libssh2_NB_state_idle; + } + return NULL; + } + + session->sftpInit_state = libssh2_NB_state_sent; + } + + if (session->sftpInit_state == libssh2_NB_state_sent) { + int ret = _libssh2_channel_process_startup(session->sftpInit_channel, + "subsystem", + sizeof("subsystem") - 1, "sftp", + strlen("sftp")); + if (ret == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block to request SFTP subsystem"); + return NULL; + } else if (ret) { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to request SFTP subsystem"); + goto sftp_init_error; + } + + session->sftpInit_state = libssh2_NB_state_sent1; + } + + if (session->sftpInit_state == libssh2_NB_state_sent1) { + rc = _libssh2_channel_extended_data(session->sftpInit_channel, + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting handle extended data"); + return NULL; + } + + sftp_handle = + session->sftpInit_sftp = + LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP)); + if (!sftp_handle) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a new SFTP structure"); + goto sftp_init_error; + } + sftp_handle->channel = session->sftpInit_channel; + sftp_handle->request_id = 0; + + _libssh2_htonu32(session->sftpInit_buffer, 5); + session->sftpInit_buffer[4] = SSH_FXP_INIT; + _libssh2_htonu32(session->sftpInit_buffer + 5, LIBSSH2_SFTP_VERSION); + session->sftpInit_sent = 0; /* nothing's sent yet */ + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Sending FXP_INIT packet advertising version %d support", + (int) LIBSSH2_SFTP_VERSION); + + session->sftpInit_state = libssh2_NB_state_sent2; + } + + if (session->sftpInit_state == libssh2_NB_state_sent2) { + /* sent off what's left of the init buffer to send */ + rc = _libssh2_channel_write(session->sftpInit_channel, 0, + session->sftpInit_buffer + + session->sftpInit_sent, + 9 - session->sftpInit_sent); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending SSH_FXP_INIT"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send SSH_FXP_INIT"); + goto sftp_init_error; + } + else { + /* add up the number of bytes sent */ + session->sftpInit_sent += rc; + + if(session->sftpInit_sent == 9) + /* move on */ + session->sftpInit_state = libssh2_NB_state_sent3; + + /* if less than 9, we remain in this state to send more later on */ + } + } + + rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION, + 0, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return NULL; + else if (rc) { + _libssh2_error(session, rc, + "Timeout waiting for response from SFTP subsystem"); + goto sftp_init_error; + } + if (data_len < 5) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Invalid SSH_FXP_VERSION response"); + LIBSSH2_FREE(session, data); + goto sftp_init_error; + } + + s = data + 1; + sftp_handle->version = _libssh2_ntohu32(s); + s += 4; + if (sftp_handle->version > LIBSSH2_SFTP_VERSION) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Truncating remote SFTP version from %lu", + sftp_handle->version); + sftp_handle->version = LIBSSH2_SFTP_VERSION; + } + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Enabling SFTP version %lu compatibility", + sftp_handle->version); + while (s < (data + data_len)) { + size_t extname_len, extdata_len; + + extname_len = _libssh2_ntohu32(s); + s += 4; + /* the extension name starts here */ + s += extname_len; + + extdata_len = _libssh2_ntohu32(s); + s += 4; + + /* TODO: Actually process extensions */ + s += extdata_len; + + } + LIBSSH2_FREE(session, data); + + /* Make sure that when the channel gets closed, the SFTP service is shut + down too */ + sftp_handle->channel->abstract = sftp_handle; + sftp_handle->channel->close_cb = libssh2_sftp_dtor; + + session->sftpInit_state = libssh2_NB_state_idle; + + /* clear the sftp and channel pointers in this session struct now */ + session->sftpInit_sftp = NULL; + session->sftpInit_channel = NULL; + + _libssh2_list_init(&sftp_handle->sftp_handles); + + return sftp_handle; + + sftp_init_error: + while (_libssh2_channel_free(session->sftpInit_channel) == + LIBSSH2_ERROR_EAGAIN); + session->sftpInit_channel = NULL; + if (session->sftpInit_sftp) { + LIBSSH2_FREE(session, session->sftpInit_sftp); + session->sftpInit_sftp = NULL; + } + session->sftpInit_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_sftp_init + * + * Startup an SFTP session + */ +LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_SFTP *ptr; + + if(!session) + return NULL; + + if(!(session->state & LIBSSH2_STATE_AUTHENTICATED)) { + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "session not authenticated yet"); + return NULL; + } + + BLOCK_ADJUST_ERRNO(ptr, session, sftp_init(session)); + return ptr; +} + +/* + * sftp_shutdown + * + * Shuts down the SFTP subsystem + */ +static int +sftp_shutdown(LIBSSH2_SFTP *sftp) +{ + int rc; + LIBSSH2_SESSION *session = sftp->channel->session; + /* + * Make sure all memory used in the state variables are free + */ + if (sftp->partial_packet) { + LIBSSH2_FREE(session, sftp->partial_packet); + sftp->partial_packet = NULL; + } + if (sftp->open_packet) { + LIBSSH2_FREE(session, sftp->open_packet); + sftp->open_packet = NULL; + } + if (sftp->readdir_packet) { + LIBSSH2_FREE(session, sftp->readdir_packet); + sftp->readdir_packet = NULL; + } + if (sftp->fstat_packet) { + LIBSSH2_FREE(session, sftp->fstat_packet); + sftp->fstat_packet = NULL; + } + if (sftp->unlink_packet) { + LIBSSH2_FREE(session, sftp->unlink_packet); + sftp->unlink_packet = NULL; + } + if (sftp->rename_packet) { + LIBSSH2_FREE(session, sftp->rename_packet); + sftp->rename_packet = NULL; + } + if (sftp->fstatvfs_packet) { + LIBSSH2_FREE(session, sftp->fstatvfs_packet); + sftp->fstatvfs_packet = NULL; + } + if (sftp->statvfs_packet) { + LIBSSH2_FREE(session, sftp->statvfs_packet); + sftp->statvfs_packet = NULL; + } + if (sftp->mkdir_packet) { + LIBSSH2_FREE(session, sftp->mkdir_packet); + sftp->mkdir_packet = NULL; + } + if (sftp->rmdir_packet) { + LIBSSH2_FREE(session, sftp->rmdir_packet); + sftp->rmdir_packet = NULL; + } + if (sftp->stat_packet) { + LIBSSH2_FREE(session, sftp->stat_packet); + sftp->stat_packet = NULL; + } + if (sftp->symlink_packet) { + LIBSSH2_FREE(session, sftp->symlink_packet); + sftp->symlink_packet = NULL; + } + if (sftp->fsync_packet) { + LIBSSH2_FREE(session, sftp->fsync_packet); + sftp->fsync_packet = NULL; + } + + sftp_packet_flush(sftp); + + /* TODO: We should consider walking over the sftp_handles list and kill + * any remaining sftp handles ... */ + + rc = _libssh2_channel_free(sftp->channel); + + return rc; +} + +/* libssh2_sftp_shutdown + * Shutsdown the SFTP subsystem + */ +LIBSSH2_API int +libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, sftp_shutdown(sftp)); + return rc; +} + +/* ******************************* + * SFTP File and Directory Ops * + ******************************* */ + +/* sftp_open + */ +static LIBSSH2_SFTP_HANDLE * +sftp_open(LIBSSH2_SFTP *sftp, const char *filename, + size_t filename_len, uint32_t flags, long mode, + int open_type) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_HANDLE *fp; + LIBSSH2_SFTP_ATTRIBUTES attrs = { + LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 + }; + unsigned char *s; + ssize_t rc; + int open_file = (open_type == LIBSSH2_SFTP_OPENFILE)?1:0; + + if (sftp->open_state == libssh2_NB_state_idle) { + /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + + flags(4) */ + sftp->open_packet_len = filename_len + 13 + + (open_file? (4 + sftp_attrsize(LIBSSH2_SFTP_ATTR_PERMISSIONS)) : 0); + + /* surprise! this starts out with nothing sent */ + sftp->open_packet_sent = 0; + s = sftp->open_packet = LIBSSH2_ALLOC(session, sftp->open_packet_len); + if (!sftp->open_packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_OPEN or " + "FXP_OPENDIR packet"); + return NULL; + } + /* Filetype in SFTP 3 and earlier */ + attrs.permissions = mode | + (open_file ? LIBSSH2_SFTP_ATTR_PFILETYPE_FILE : + LIBSSH2_SFTP_ATTR_PFILETYPE_DIR); + + _libssh2_store_u32(&s, sftp->open_packet_len - 4); + *(s++) = open_file? SSH_FXP_OPEN : SSH_FXP_OPENDIR; + sftp->open_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->open_request_id); + _libssh2_store_str(&s, filename, filename_len); + + if (open_file) { + _libssh2_store_u32(&s, flags); + s += sftp_attr2bin(s, &attrs); + } + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Sending %s open request", + open_file? "file" : "directory"); + + sftp->open_state = libssh2_NB_state_created; + } + + if (sftp->open_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->open_packet+ + sftp->open_packet_sent, + sftp->open_packet_len - + sftp->open_packet_sent); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending FXP_OPEN or FXP_OPENDIR command"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, rc, "Unable to send FXP_OPEN*"); + LIBSSH2_FREE(session, sftp->open_packet); + sftp->open_packet = NULL; + sftp->open_state = libssh2_NB_state_idle; + return NULL; + } + + /* bump the sent counter and remain in this state until the whole + data is off */ + sftp->open_packet_sent += rc; + + if(sftp->open_packet_len == sftp->open_packet_sent) { + LIBSSH2_FREE(session, sftp->open_packet); + sftp->open_packet = NULL; + + sftp->open_state = libssh2_NB_state_sent; + } + } + + if (sftp->open_state == libssh2_NB_state_sent) { + size_t data_len; + unsigned char *data; + static const unsigned char fopen_responses[2] = + { SSH_FXP_HANDLE, SSH_FXP_STATUS }; + rc = sftp_packet_requirev(sftp, 2, fopen_responses, + sftp->open_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for status message"); + return NULL; + } + sftp->open_state = libssh2_NB_state_idle; + if (rc) { + _libssh2_error(session, rc, "Timeout waiting for status message"); + return NULL; + } + + /* OPEN can basically get STATUS or HANDLE back, where HANDLE implies + a fine response while STATUS means error. It seems though that at + times we get an SSH_FX_OK back in a STATUS, followed the "real" + HANDLE so we need to properly deal with that. */ + if (data[0] == SSH_FXP_STATUS) { + int badness = 1; + + if(data_len < 9) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Too small FXP_STATUS"); + LIBSSH2_FREE(session, data); + return NULL; + } + + sftp->last_errno = _libssh2_ntohu32(data + 5); + + if(LIBSSH2_FX_OK == sftp->last_errno) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "got HANDLE FXOK!"); + + LIBSSH2_FREE(session, data); + + /* silly situation, but check for a HANDLE */ + rc = sftp_packet_require(sftp, SSH_FXP_HANDLE, + sftp->open_request_id, &data, + &data_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + /* go back to sent state and wait for something else */ + sftp->open_state = libssh2_NB_state_sent; + return NULL; + } + else if(!rc) + /* we got the handle so this is not a bad situation */ + badness = 0; + } + + if(badness) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Failed opening remote file"); + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "got FXP_STATUS %d", + sftp->last_errno); + LIBSSH2_FREE(session, data); + return NULL; + } + } + + if(data_len < 10) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Too small FXP_HANDLE"); + LIBSSH2_FREE(session, data); + return NULL; + } + + fp = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE)); + if (!fp) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate new SFTP handle structure"); + LIBSSH2_FREE(session, data); + return NULL; + } + fp->handle_type = open_file ? LIBSSH2_SFTP_HANDLE_FILE : + LIBSSH2_SFTP_HANDLE_DIR; + + fp->handle_len = _libssh2_ntohu32(data + 5); + if (fp->handle_len > SFTP_HANDLE_MAXLEN) + /* SFTP doesn't allow handles longer than 256 characters */ + fp->handle_len = SFTP_HANDLE_MAXLEN; + + if(fp->handle_len > (data_len - 9)) + /* do not reach beyond the end of the data we got */ + fp->handle_len = data_len - 9; + + memcpy(fp->handle, data + 9, fp->handle_len); + + LIBSSH2_FREE(session, data); + + /* add this file handle to the list kept in the sftp session */ + _libssh2_list_add(&sftp->sftp_handles, &fp->node); + + fp->sftp = sftp; /* point to the parent struct */ + + fp->u.file.offset = 0; + fp->u.file.offset_sent = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Open command successful"); + return fp; + } + return NULL; +} + +/* libssh2_sftp_open_ex + */ +LIBSSH2_API LIBSSH2_SFTP_HANDLE * +libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, + unsigned int filename_len, unsigned long flags, long mode, + int open_type) +{ + LIBSSH2_SFTP_HANDLE *hnd; + + if(!sftp) + return NULL; + + BLOCK_ADJUST_ERRNO(hnd, sftp->channel->session, + sftp_open(sftp, filename, filename_len, flags, mode, + open_type)); + return hnd; +} + +/* + * sftp_read + * + * Read from an SFTP file handle + * + */ +static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer, + size_t buffer_size) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t count = 0; + struct sftp_pipeline_chunk *chunk; + struct sftp_pipeline_chunk *next; + ssize_t rc; + struct _libssh2_sftp_handle_file_data *filep = + &handle->u.file; + size_t bytes_in_buffer = 0; + char *sliding_bufferp = buffer; + + /* This function can be interrupted in three different places where it + might need to wait for data from the network. It returns EAGAIN to + allow non-blocking clients to do other work but these client are + expected to call this function again (possibly many times) to finish + the operation. + + The tricky part is that if we previously aborted a sftp_read due to + EAGAIN, we must continue at the same spot to continue the previously + interrupted operation. This is done using a state machine to record + what phase of execution we were at. The state is stored in + sftp->read_state. + + libssh2_NB_state_idle: The first phase is where we prepare multiple + FXP_READ packets to do optimistic read-ahead. We send off as many as + possible in the second phase without waiting for a response to each + one; this is the key to fast reads. But we may have to adjust the + channel window size to do this which may interrupt this function while + waiting. The state machine saves the phase as libssh2_NB_state_idle so + it returns here on the next call. + + libssh2_NB_state_sent: The second phase is where we send the FXP_READ + packets. Writing them to the channel can be interrupted with EAGAIN + but the state machine ensures we skip the first phase on the next call + and resume sending. + + libssh2_NB_state_sent2: In the third phase (indicated by ) we read the + data from the responses that have arrived so far. Reading can be + interrupted with EAGAIN but the state machine ensures we skip the first + and second phases on the next call and resume sending. + */ + + switch (sftp->read_state) { + case libssh2_NB_state_idle: + + /* Some data may already have been read from the server in the + previous call but didn't fit in the buffer at the time. If so, we + return that now as we can't risk being interrupted later with data + partially written to the buffer. */ + if(filep->data_left) { + size_t copy = MIN(buffer_size, filep->data_left); + + memcpy(buffer, &filep->data[ filep->data_len - filep->data_left], + copy); + + filep->data_left -= copy; + filep->offset += copy; + + if(!filep->data_left) { + LIBSSH2_FREE(session, filep->data); + filep->data = NULL; + } + + return copy; + } + + if (filep->eof) { + return 0; + } else { + /* We allow a number of bytes being requested at any given time + without having been acked - until we reach EOF. */ + + /* Number of bytes asked for that haven't been acked yet */ + size_t already = (size_t)(filep->offset_sent - filep->offset); + + size_t max_read_ahead = buffer_size*4; + unsigned long recv_window; + + if(max_read_ahead > LIBSSH2_CHANNEL_WINDOW_DEFAULT*4) + max_read_ahead = LIBSSH2_CHANNEL_WINDOW_DEFAULT*4; + + /* if the buffer_size passed in now is smaller than what has + already been sent, we risk getting count become a very large + number */ + if(max_read_ahead > already) + count = max_read_ahead - already; + + /* 'count' is how much more data to ask for, and 'already' is how + much data that already has been asked for but not yet returned. + Specificly, 'count' means how much data that have or will be + asked for by the nodes that are already added to the linked + list. Some of those read requests may not actually have been + sent off successfully yet. + + If 'already' is very large it should be perfectly fine to have + count set to 0 as then we don't have to ask for more data + (right now). + + buffer_size*4 is just picked more or less out of the air. The + idea is that when reading SFTP from a remote server, we send + away multiple read requests guessing that the client will read + more than only this 'buffer_size' amount of memory. So we ask + for maximum buffer_size*4 amount of data so that we can return + them very fast in subsequent calls. + */ + + recv_window = libssh2_channel_window_read_ex(sftp->channel, + NULL, NULL); + if(max_read_ahead > recv_window) { + /* more data will be asked for than what the window currently + allows, expand it! */ + + rc = _libssh2_channel_receive_window_adjust(sftp->channel, + max_read_ahead*8, + 1, NULL); + /* if this returns EAGAIN, we will get back to this function + at next call */ + assert(rc != LIBSSH2_ERROR_EAGAIN || !filep->data_left); + assert(rc != LIBSSH2_ERROR_EAGAIN || !filep->eof); + if (rc) + return rc; + } + } + + while(count > 0) { + unsigned char *s; + + /* 25 = packet_len(4) + packet_type(1) + request_id(4) + + handle_len(4) + offset(8) + count(4) */ + uint32_t packet_len = (uint32_t)handle->handle_len + 25; + uint32_t request_id; + + uint32_t size = count; + if (size < buffer_size) + size = buffer_size; + if (size > MAX_SFTP_READ_SIZE) + size = MAX_SFTP_READ_SIZE; + + chunk = LIBSSH2_ALLOC(session, packet_len + + sizeof(struct sftp_pipeline_chunk)); + if (!chunk) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "malloc fail for FXP_WRITE"); + + chunk->offset = filep->offset_sent; + chunk->len = size; + chunk->lefttosend = packet_len; + chunk->sent = 0; + + s = chunk->packet; + + _libssh2_store_u32(&s, packet_len - 4); + *s++ = SSH_FXP_READ; + request_id = sftp->request_id++; + chunk->request_id = request_id; + _libssh2_store_u32(&s, request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + _libssh2_store_u64(&s, filep->offset_sent); + filep->offset_sent += size; /* advance offset at once */ + _libssh2_store_u32(&s, size); + + /* add this new entry LAST in the list */ + _libssh2_list_add(&handle->packet_list, &chunk->node); + count -= MIN(size,count); /* deduct the size we used, as we might + * have to create more packets */ + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "read request id %d sent (offset: %d, size: %d)", + request_id, (int)chunk->offset, (int)chunk->len); + } + + case libssh2_NB_state_sent: + + sftp->read_state = libssh2_NB_state_idle; + + /* move through the READ packets that haven't been sent and send as + many as possible - remember that we don't block */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + if(chunk->lefttosend) { + + rc = _libssh2_channel_write(channel, 0, + &chunk->packet[chunk->sent], + chunk->lefttosend); + if(rc < 0) { + sftp->read_state = libssh2_NB_state_sent; + return rc; + } + + /* remember where to continue sending the next time */ + chunk->lefttosend -= rc; + chunk->sent += rc; + + if(chunk->lefttosend) { + /* We still have data left to send for this chunk. + * If there is at least one completely sent chunk, + * we can get out of this loop and start reading. */ + if (chunk != _libssh2_list_first(&handle->packet_list)) { + break; + } else { + continue; + } + } + } + + /* move on to the next chunk with data to send */ + chunk = _libssh2_list_next(&chunk->node); + } + + case libssh2_NB_state_sent2: + + sftp->read_state = libssh2_NB_state_idle; + + /* + * Count all ACKed packets and act on the contents of them. + */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + unsigned char *data; + size_t data_len; + uint32_t rc32; + static const unsigned char read_responses[2] = { + SSH_FXP_DATA, SSH_FXP_STATUS + }; + + if(chunk->lefttosend) { + /* if the chunk still has data left to send, we shouldn't wait + for an ACK for it just yet */ + if (bytes_in_buffer > 0) { + return bytes_in_buffer; + } else { + /* we should never reach this point */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "sftp_read() internal error"); + } + } + + rc = sftp_packet_requirev(sftp, 2, read_responses, + chunk->request_id, &data, &data_len); + + if (rc==LIBSSH2_ERROR_EAGAIN && bytes_in_buffer != 0) { + /* do not return EAGAIN if we have already + * written data into the buffer */ + return bytes_in_buffer; + } + + if (rc < 0) { + sftp->read_state = libssh2_NB_state_sent2; + return rc; + } + + /* + * We get DATA or STATUS back. STATUS can be error, or it is + * FX_EOF when we reach the end of the file. + */ + + switch (data[0]) { + case SSH_FXP_STATUS: + /* remove the chunk we just processed */ + + _libssh2_list_remove(&chunk->node); + LIBSSH2_FREE(session, chunk); + + /* we must remove all outstanding READ requests, as either we + got an error or we're at end of file */ + sftp_packetlist_flush(handle); + + rc32 = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (rc32 == LIBSSH2_FX_EOF) { + filep->eof = TRUE; + return bytes_in_buffer; + } + else { + sftp->last_errno = rc32; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP READ error"); + } + break; + + case SSH_FXP_DATA: + if (chunk->offset != filep->offset) { + /* This could happen if the server returns less bytes than + requested, which shouldn't happen for normal files. See: + https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02 + #section-6.4 + */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Read Packet At Unexpected Offset"); + } + + rc32 = _libssh2_ntohu32(data + 5); + if (rc32 > (data_len - 9)) + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol badness"); + + if(rc32 > chunk->len) { + /* A chunk larger than we requested was returned to us. + This is a protocol violation and we don't know how to + deal with it. Bail out! */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "FXP_READ response too big"); + } + + if(rc32 != chunk->len) { + /* a short read does not imply end of file, but we must + adjust the offset_sent since it was advanced with a + full chunk->len before */ + filep->offset_sent -= (chunk->len - rc32); + } + + if((bytes_in_buffer + rc32) > buffer_size) { + /* figure out the overlap amount */ + filep->data_left = (bytes_in_buffer + rc32) - buffer_size; + + /* getting the full packet would overflow the buffer, so + only get the correct amount and keep the remainder */ + rc32 = (uint32_t)buffer_size - bytes_in_buffer; + + /* store data to keep for next call */ + filep->data = data; + filep->data_len = data_len; + } + else + filep->data_len = 0; + + /* copy the received data from the received FXP_DATA packet to + the buffer at the correct index */ + memcpy(sliding_bufferp, data + 9, rc32); + filep->offset += rc32; + bytes_in_buffer += rc32; + sliding_bufferp += rc32; + + if(filep->data_len == 0) + /* free the allocated data if not stored to keep */ + LIBSSH2_FREE(session, data); + + /* remove the chunk we just processed keeping track of the + * next one in case we need it */ + next = _libssh2_list_next(&chunk->node); + _libssh2_list_remove(&chunk->node); + LIBSSH2_FREE(session, chunk); + + /* check if we have space left in the buffer + * and either continue to the next chunk or stop + */ + if (bytes_in_buffer < buffer_size) { + chunk = next; + } else { + chunk = NULL; + } + + break; + default: + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol badness: unrecognised " + "read request response"); + } + } + + if (bytes_in_buffer > 0) + return bytes_in_buffer; + + break; + + default: + assert(!"State machine error; unrecognised read state"); + } + + /* we should never reach this point */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "sftp_read() internal error"); +} + +/* libssh2_sftp_read + * Read from an SFTP file handle + */ +LIBSSH2_API ssize_t +libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *hnd, char *buffer, + size_t buffer_maxlen) +{ + ssize_t rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_read(hnd, buffer, buffer_maxlen)); + return rc; +} + +/* sftp_readdir + * Read from an SFTP directory handle + */ +static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, + size_t buffer_maxlen, char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + uint32_t num_names; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + uint32_t packet_len = handle->handle_len + 13; + unsigned char *s, *data; + static const unsigned char read_responses[2] = { + SSH_FXP_NAME, SSH_FXP_STATUS }; + ssize_t retcode; + + if (sftp->readdir_state == libssh2_NB_state_idle) { + if (handle->u.dir.names_left) { + /* + * A prior request returned more than one directory entry, + * feed it back from the buffer + */ + LIBSSH2_SFTP_ATTRIBUTES attrs_dummy; + size_t real_longentry_len; + size_t real_filename_len; + size_t filename_len; + size_t longentry_len; + + s = (unsigned char *) handle->u.dir.next_name; + real_filename_len = _libssh2_ntohu32(s); + + s += 4; + + filename_len = real_filename_len; + if (filename_len >= buffer_maxlen) { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + memcpy(buffer, s, filename_len); + buffer[filename_len] = '\0'; /* zero terminate */ + s += real_filename_len; + + real_longentry_len = _libssh2_ntohu32(s); + s += 4; + + if (longentry && (longentry_maxlen>1)) { + longentry_len = real_longentry_len; + + if (longentry_len >= longentry_maxlen) { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + memcpy(longentry, s, longentry_len); + longentry[longentry_len] = '\0'; /* zero terminate */ + } + s += real_longentry_len; + + if (attrs) + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + + s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s); + + handle->u.dir.next_name = (char *) s; + end: + + if ((--handle->u.dir.names_left) == 0) + LIBSSH2_FREE(session, handle->u.dir.names_packet); + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "libssh2_sftp_readdir_ex() return %d", + filename_len); + return (ssize_t)filename_len; + } + + /* Request another entry(entries?) */ + + s = sftp->readdir_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->readdir_packet) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "FXP_READDIR packet"); + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_READDIR; + sftp->readdir_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->readdir_request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + sftp->readdir_state = libssh2_NB_state_created; + } + + if (sftp->readdir_state == libssh2_NB_state_created) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Reading entries from directory handle"); + retcode = _libssh2_channel_write(channel, 0, sftp->readdir_packet, + packet_len); + if (retcode == LIBSSH2_ERROR_EAGAIN) { + return retcode; + } + else if ((ssize_t)packet_len != retcode) { + LIBSSH2_FREE(session, sftp->readdir_packet); + sftp->readdir_packet = NULL; + sftp->readdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + + LIBSSH2_FREE(session, sftp->readdir_packet); + sftp->readdir_packet = NULL; + + sftp->readdir_state = libssh2_NB_state_sent; + } + + retcode = sftp_packet_requirev(sftp, 2, read_responses, + sftp->readdir_request_id, &data, + &data_len); + if (retcode == LIBSSH2_ERROR_EAGAIN) + return retcode; + else if (retcode) { + sftp->readdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, retcode, + "Timeout waiting for status message"); + } + + if (data[0] == SSH_FXP_STATUS) { + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_EOF) { + sftp->readdir_state = libssh2_NB_state_idle; + return 0; + } + else { + sftp->last_errno = retcode; + sftp->readdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + sftp->readdir_state = libssh2_NB_state_idle; + + num_names = _libssh2_ntohu32(data + 5); + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%lu entries returned", + num_names); + if (!num_names) { + LIBSSH2_FREE(session, data); + return 0; + } + + handle->u.dir.names_left = num_names; + handle->u.dir.names_packet = data; + handle->u.dir.next_name = (char *) data + 9; + + /* use the name popping mechanism from the start of the function */ + return sftp_readdir(handle, buffer, buffer_maxlen, longentry, + longentry_maxlen, attrs); +} + +/* libssh2_sftp_readdir_ex + * Read from an SFTP directory handle + */ +LIBSSH2_API int +libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *hnd, char *buffer, + size_t buffer_maxlen, char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs) +{ + int rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_readdir(hnd, buffer, buffer_maxlen, longentry, + longentry_maxlen, attrs)); + return rc; +} + +/* + * sftp_write + * + * Write data to an SFTP handle. Returns the number of bytes written, or + * a negative error code. + * + * We recommend sending very large data buffers to this function! + * + * Concept: + * + * - Detect how much of the given buffer that was already sent in a previous + * call by inspecting the linked list of outgoing chunks. Make sure to skip + * passed the data that has already been taken care of. + * + * - Split all (new) outgoing data in chunks no larger than N. + * + * - Each N bytes chunk gets created as a separate SFTP packet. + * + * - Add all created outgoing packets to the linked list. + * + * - Walk through the list and send the chunks that haven't been sent, + * as many as possible until EAGAIN. Some of the chunks may have been put + * in the list in a previous invoke. + * + * - For all the chunks in the list that have been completely sent off, check + * for ACKs. If a chunk has been ACKed, it is removed from the linked + * list and the "acked" counter gets increased with that data amount. + * + * - Return TOTAL bytes acked so far. + * + * Caveats: + * - be careful: we must not return a higher number than what was given! + * + * TODO: + * Introduce an option that disables this sort of "speculative" ahead writing + * as there's a risk that it will do harm to some app. + */ + +static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, + size_t count) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + uint32_t retcode; + uint32_t packet_len; + unsigned char *s, *data; + ssize_t rc; + struct sftp_pipeline_chunk *chunk; + struct sftp_pipeline_chunk *next; + size_t acked = 0; + size_t org_count = count; + size_t already; + + switch(sftp->write_state) { + default: + case libssh2_NB_state_idle: + + /* Number of bytes sent off that haven't been acked and therefor we + will get passed in here again. + + Also, add up the number of bytes that actually already have been + acked but we haven't been able to return as such yet, so we will + get that data as well passed in here again. + */ + already = (size_t) (handle->u.file.offset_sent - handle->u.file.offset)+ + handle->u.file.acked; + + if(count >= already) { + /* skip the part already made into packets */ + buffer += already; + count -= already; + } + else + /* there is more data already fine than what we got in this call */ + count = 0; + + sftp->write_state = libssh2_NB_state_idle; + while(count) { + /* TODO: Possibly this should have some logic to prevent a very + very small fraction to be left but lets ignore that for now */ + uint32_t size = MIN(MAX_SFTP_OUTGOING_SIZE, count); + uint32_t request_id; + + /* 25 = packet_len(4) + packet_type(1) + request_id(4) + + handle_len(4) + offset(8) + count(4) */ + packet_len = handle->handle_len + size + 25; + + chunk = LIBSSH2_ALLOC(session, packet_len + + sizeof(struct sftp_pipeline_chunk)); + if (!chunk) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "malloc fail for FXP_WRITE"); + + chunk->len = size; + chunk->sent = 0; + chunk->lefttosend = packet_len; + + s = chunk->packet; + _libssh2_store_u32(&s, packet_len - 4); + + *(s++) = SSH_FXP_WRITE; + request_id = sftp->request_id++; + chunk->request_id = request_id; + _libssh2_store_u32(&s, request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + _libssh2_store_u64(&s, handle->u.file.offset_sent); + handle->u.file.offset_sent += size; /* advance offset at once */ + _libssh2_store_str(&s, buffer, size); + + /* add this new entry LAST in the list */ + _libssh2_list_add(&handle->packet_list, &chunk->node); + + buffer += size; + count -= size; /* deduct the size we used, as we might have + to create more packets */ + } + + /* move through the WRITE packets that haven't been sent and send as many + as possible - remember that we don't block */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + if(chunk->lefttosend) { + rc = _libssh2_channel_write(channel, 0, + &chunk->packet[chunk->sent], + chunk->lefttosend); + if(rc < 0) + /* remain in idle state */ + return rc; + + /* remember where to continue sending the next time */ + chunk->lefttosend -= rc; + chunk->sent += rc; + + if(chunk->lefttosend) + /* data left to send, get out of loop */ + break; + } + + /* move on to the next chunk with data to send */ + chunk = _libssh2_list_next(&chunk->node); + } + + /* fall-through */ + case libssh2_NB_state_sent: + + sftp->write_state = libssh2_NB_state_idle; + /* + * Count all ACKed packets + */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + if(chunk->lefttosend) + /* if the chunk still has data left to send, we shouldn't wait + for an ACK for it just yet */ + break; + + else if(acked) + /* if we have sent data that is acked, we must return that + info before we call a function that might return EAGAIN */ + break; + + /* we check the packets in order */ + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + chunk->request_id, &data, &data_len); + if (rc < 0) { + if (rc == LIBSSH2_ERROR_EAGAIN) + sftp->write_state = libssh2_NB_state_sent; + return rc; + } + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + sftp->last_errno = retcode; + if (retcode == LIBSSH2_FX_OK) { + acked += chunk->len; /* number of payload data that was acked + here */ + + /* we increase the offset value for all acks */ + handle->u.file.offset += chunk->len; + + next = _libssh2_list_next(&chunk->node); + + _libssh2_list_remove(&chunk->node); /* remove from list */ + LIBSSH2_FREE(session, chunk); /* free memory */ + + chunk = next; + } + else { + /* flush all pending packets from the outgoing list */ + sftp_packetlist_flush(handle); + + /* since we return error now, the application will not get any + outstanding data acked, so we need to rewind the offset to + where the application knows it has reached with acked data */ + handle->u.file.offset -= handle->u.file.acked; + + /* then reset the offset_sent to be the same as the offset */ + handle->u.file.offset_sent = handle->u.file.offset; + + /* clear the acked counter since we can have no pending data to + ack after an error */ + handle->u.file.acked = 0; + + /* the server returned an error for that written chunk, propagate + this back to our parent function */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "FXP write failed"); + } + } + break; + } + + /* if there were acked data in a previous call that wasn't returned then, + add that up and try to return it all now. This can happen if the app + first sends a huge buffer of data, and then in a second call it sends a + smaller one. */ + acked += handle->u.file.acked; + + if(acked) { + ssize_t ret = MIN(acked, org_count); + /* we got data acked so return that amount, but no more than what + was asked to get sent! */ + + /* store the remainder. 'ret' is always equal to or less than 'acked' + here */ + handle->u.file.acked = acked - ret; + + return ret; + } + + else + return 0; /* nothing was acked, and no EAGAIN was received! */ +} + +/* libssh2_sftp_write + * Write data to a file handle + */ +LIBSSH2_API ssize_t +libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *hnd, const char *buffer, + size_t count) +{ + ssize_t rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_write(hnd, buffer, count)); + return rc; + +} + +static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + /* 34 = packet_len(4) + packet_type(1) + request_id(4) + + string_len(4) + strlen("fsync@openssh.com")(17) + handle_len(4) */ + uint32_t packet_len = handle->handle_len + 34; + size_t data_len; + unsigned char *packet, *s, *data; + ssize_t rc; + uint32_t retcode; + + if (sftp->fsync_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Issuing fsync command"); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_EXTENDED " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_EXTENDED; + sftp->fsync_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->fsync_request_id); + _libssh2_store_str(&s, "fsync@openssh.com", 17); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + sftp->fsync_state = libssh2_NB_state_created; + } else { + packet = sftp->fsync_packet; + } + + if (sftp->fsync_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN || + (0 <= rc && rc < (ssize_t)packet_len)) { + sftp->fsync_packet = packet; + return LIBSSH2_ERROR_EAGAIN; + } + + LIBSSH2_FREE(session, packet); + sftp->fsync_packet = NULL; + + if (rc < 0) { + sftp->fsync_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + sftp->fsync_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->fsync_request_id, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->fsync_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP EXTENDED REPLY"); + } + + sftp->fsync_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode != LIBSSH2_FX_OK) { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "fsync failed"); + } + + return 0; +} + +/* libssh2_sftp_fsync + * Commit data on the handle to disk. + */ +LIBSSH2_API int +libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *hnd) +{ + int rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_fsync(hnd)); + return rc; +} + + +/* + * sftp_fstat + * + * Get or Set stat on a file + */ +static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + uint32_t packet_len = + handle->handle_len + 13 + (setstat ? sftp_attrsize(attrs->flags) : 0); + unsigned char *s, *data; + static const unsigned char fstat_responses[2] = + { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + ssize_t rc; + + if (sftp->fstat_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Issuing %s command", + setstat ? "set-stat" : "stat"); + s = sftp->fstat_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->fstat_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "FSTAT/FSETSTAT packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = setstat ? SSH_FXP_FSETSTAT : SSH_FXP_FSTAT; + sftp->fstat_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->fstat_request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + if (setstat) { + s += sftp_attr2bin(s, attrs); + } + + sftp->fstat_state = libssh2_NB_state_created; + } + + if (sftp->fstat_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->fstat_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if ((ssize_t)packet_len != rc) { + LIBSSH2_FREE(session, sftp->fstat_packet); + sftp->fstat_packet = NULL; + sftp->fstat_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + (setstat ? "Unable to send FXP_FSETSTAT" + : "Unable to send FXP_FSTAT command")); + } + LIBSSH2_FREE(session, sftp->fstat_packet); + sftp->fstat_packet = NULL; + + sftp->fstat_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, fstat_responses, + sftp->fstat_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (rc) { + sftp->fstat_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Timeout waiting for status message"); + } + + sftp->fstat_state = libssh2_NB_state_idle; + + if (data[0] == SSH_FXP_STATUS) { + uint32_t retcode; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + sftp_bin2attr(attrs, data + 5); + LIBSSH2_FREE(session, data); + + return 0; +} + +/* libssh2_sftp_fstat_ex + * Get or Set stat on a file + */ +LIBSSH2_API int +libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *hnd, + LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) +{ + int rc; + if(!hnd || !attrs) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_fstat(hnd, attrs, setstat)); + return rc; +} + + +/* libssh2_sftp_seek64 + * Set the read/write pointer to an arbitrary position within the file + */ +LIBSSH2_API void +libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset) +{ + if(!handle) + return; + if(handle->u.file.offset == offset && handle->u.file.offset_sent == offset) + return; + + handle->u.file.offset = handle->u.file.offset_sent = offset; + /* discard all pending requests and currently read data */ + sftp_packetlist_flush(handle); + + /* free the left received buffered data */ + if (handle->u.file.data_left) { + LIBSSH2_FREE(handle->sftp->channel->session, handle->u.file.data); + handle->u.file.data_left = handle->u.file.data_len = 0; + handle->u.file.data = NULL; + } + + /* reset EOF to False */ + handle->u.file.eof = FALSE; +} + +/* libssh2_sftp_seek + * Set the read/write pointer to an arbitrary position within the file + */ +LIBSSH2_API void +libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset) +{ + libssh2_sftp_seek64(handle, (libssh2_uint64_t)offset); +} + +/* libssh2_sftp_tell + * Return the current read/write pointer's offset + */ +LIBSSH2_API size_t +libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle) +{ + if(!handle) + return 0; /* no handle, no size */ + + /* NOTE: this may very well truncate the size if it is larger than what + size_t can hold, so libssh2_sftp_tell64() is really the function you + should use */ + return (size_t)(handle->u.file.offset); +} + +/* libssh2_sftp_tell64 + * Return the current read/write pointer's offset + */ +LIBSSH2_API libssh2_uint64_t +libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle) +{ + if(!handle) + return 0; /* no handle, no size */ + + return handle->u.file.offset; +} + +/* + * Flush all remaining incoming SFTP packets and zombies. + */ +static void sftp_packet_flush(LIBSSH2_SFTP *sftp) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets); + struct sftp_zombie_requests *zombie = + _libssh2_list_first(&sftp->zombie_requests); + + while(packet) { + LIBSSH2_SFTP_PACKET *next; + + /* check next struct in the list */ + next = _libssh2_list_next(&packet->node); + _libssh2_list_remove(&packet->node); + LIBSSH2_FREE(session, packet->data); + LIBSSH2_FREE(session, packet); + + packet = next; + } + + while(zombie) { + /* figure out the next node */ + struct sftp_zombie_requests *next = _libssh2_list_next(&zombie->node); + /* unlink the current one */ + _libssh2_list_remove(&zombie->node); + /* free the memory */ + LIBSSH2_FREE(session, zombie); + zombie = next; + } + +} + +/* sftp_close_handle + * + * Close a file or directory handle. + * Also frees handle resource and unlinks it from the SFTP structure. + * The handle is no longer usable after return of this function, unless + * the return value is LIBSSH2_ERROR_EAGAIN in which case this function + * should be called again. + */ +static int +sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + uint32_t packet_len = handle->handle_len + 13; + unsigned char *s, *data = NULL; + int rc = 0; + + if (handle->close_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Closing handle"); + s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len); + if (!handle->close_packet) { + handle->close_state = libssh2_NB_state_idle; + rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_CLOSE " + "packet"); + } else { + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_CLOSE; + handle->close_request_id = sftp->request_id++; + _libssh2_store_u32(&s, handle->close_request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + handle->close_state = libssh2_NB_state_created; + } + } + + if (handle->close_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, handle->close_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((ssize_t)packet_len != rc) { + handle->close_state = libssh2_NB_state_idle; + rc = _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_CLOSE command"); + } else + handle->close_state = libssh2_NB_state_sent; + + LIBSSH2_FREE(session, handle->close_packet); + handle->close_packet = NULL; + } + + if (handle->close_state == libssh2_NB_state_sent) { + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + handle->close_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + + } else if (rc) { + _libssh2_error(session, rc, + "Error waiting for status message"); + } + + handle->close_state = libssh2_NB_state_sent1; + } + + if(!data) { + /* if it reaches this point with data unset, something unwanted + happened for which we should have set an error code */ + assert(rc); + + } else { + int retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode != LIBSSH2_FX_OK) { + sftp->last_errno = retcode; + handle->close_state = libssh2_NB_state_idle; + rc = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + /* remove this handle from the parent's list */ + _libssh2_list_remove(&handle->node); + + if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR) + && handle->u.dir.names_left) { + LIBSSH2_FREE(session, handle->u.dir.names_packet); + } + else { + if(handle->u.file.data) + LIBSSH2_FREE(session, handle->u.file.data); + } + + sftp_packetlist_flush(handle); + sftp->read_state = libssh2_NB_state_idle; + + handle->close_state = libssh2_NB_state_idle; + + LIBSSH2_FREE(session, handle); + + return rc; +} + +/* libssh2_sftp_close_handle + * + * Close a file or directory handle + * Also frees handle resource and unlinks it from the SFTP structure + */ +LIBSSH2_API int +libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *hnd) +{ + int rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, sftp_close_handle(hnd)); + return rc; +} + +/* sftp_unlink + * Delete a file from the remote server + */ +static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename, + size_t filename_len) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + int retcode; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) */ + uint32_t packet_len = filename_len + 13; + unsigned char *s, *data; + int rc; + + if (sftp->unlink_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Unlinking %s", filename); + s = sftp->unlink_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->unlink_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_REMOVE " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_REMOVE; + sftp->unlink_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->unlink_request_id); + _libssh2_store_str(&s, filename, filename_len); + sftp->unlink_state = libssh2_NB_state_created; + } + + if (sftp->unlink_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->unlink_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((ssize_t)packet_len != rc) { + LIBSSH2_FREE(session, sftp->unlink_packet); + sftp->unlink_packet = NULL; + sftp->unlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_REMOVE command"); + } + LIBSSH2_FREE(session, sftp->unlink_packet); + sftp->unlink_packet = NULL; + + sftp->unlink_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->unlink_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if (rc) { + sftp->unlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->unlink_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } +} + +/* libssh2_sftp_unlink_ex + * Delete a file from the remote server + */ +LIBSSH2_API int +libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, + unsigned int filename_len) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_unlink(sftp, filename, filename_len)); + return rc; +} + +/* + * sftp_rename + * + * Rename a file on the remote server + */ +static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename, + unsigned int source_filename_len, + const char *dest_filename, + unsigned int dest_filename_len, long flags) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + int retcode; + uint32_t packet_len = + source_filename_len + dest_filename_len + 17 + (sftp->version >= + 5 ? 4 : 0); + /* packet_len(4) + packet_type(1) + request_id(4) + + source_filename_len(4) + dest_filename_len(4) + flags(4){SFTP5+) */ + unsigned char *data; + ssize_t rc; + + if (sftp->version < 2) { + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Server does not support RENAME"); + } + + if (sftp->rename_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Renaming %s to %s", + source_filename, dest_filename); + sftp->rename_s = sftp->rename_packet = + LIBSSH2_ALLOC(session, packet_len); + if (!sftp->rename_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_RENAME " + "packet"); + } + + _libssh2_store_u32(&sftp->rename_s, packet_len - 4); + *(sftp->rename_s++) = SSH_FXP_RENAME; + sftp->rename_request_id = sftp->request_id++; + _libssh2_store_u32(&sftp->rename_s, sftp->rename_request_id); + _libssh2_store_str(&sftp->rename_s, source_filename, + source_filename_len); + _libssh2_store_str(&sftp->rename_s, dest_filename, dest_filename_len); + + if (sftp->version >= 5) + _libssh2_store_u32(&sftp->rename_s, flags); + + sftp->rename_state = libssh2_NB_state_created; + } + + if (sftp->rename_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->rename_packet, + sftp->rename_s - sftp->rename_packet); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((ssize_t)packet_len != rc) { + LIBSSH2_FREE(session, sftp->rename_packet); + sftp->rename_packet = NULL; + sftp->rename_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_RENAME command"); + } + LIBSSH2_FREE(session, sftp->rename_packet); + sftp->rename_packet = NULL; + + sftp->rename_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->rename_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->rename_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->rename_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + sftp->last_errno = retcode; + + /* now convert the SFTP error code to libssh2 return code or error + message */ + switch (retcode) { + case LIBSSH2_FX_OK: + retcode = LIBSSH2_ERROR_NONE; + break; + + case LIBSSH2_FX_FILE_ALREADY_EXISTS: + retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "File already exists and " + "SSH_FXP_RENAME_OVERWRITE not specified"); + break; + + case LIBSSH2_FX_OP_UNSUPPORTED: + retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Operation Not Supported"); + break; + + default: + retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + break; + } + + return retcode; +} + +/* libssh2_sftp_rename_ex + * Rename a file on the remote server + */ +LIBSSH2_API int +libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, + unsigned int source_filename_len, + const char *dest_filename, + unsigned int dest_filename_len, long flags) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_rename(sftp, source_filename, source_filename_len, + dest_filename, dest_filename_len, flags)); + return rc; +} + +/* + * sftp_fstatvfs + * + * Get file system statistics + */ +static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 17 = packet_len(4) + packet_type(1) + request_id(4) + ext_len(4) + + handle_len (4) */ + /* 20 = strlen ("fstatvfs@openssh.com") */ + uint32_t packet_len = handle->handle_len + 20 + 17; + unsigned char *packet, *s, *data; + ssize_t rc; + unsigned int flag; + static const unsigned char responses[2] = + { SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS }; + + if (sftp->fstatvfs_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Getting file system statistics"); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_EXTENDED " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_EXTENDED; + sftp->fstatvfs_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->fstatvfs_request_id); + _libssh2_store_str(&s, "fstatvfs@openssh.com", 20); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + sftp->fstatvfs_state = libssh2_NB_state_created; + } + else { + packet = sftp->fstatvfs_packet; + } + + if (sftp->fstatvfs_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN || + (0 <= rc && rc < (ssize_t)packet_len)) { + sftp->fstatvfs_packet = packet; + return LIBSSH2_ERROR_EAGAIN; + } + + LIBSSH2_FREE(session, packet); + sftp->fstatvfs_packet = NULL; + + if (rc < 0) { + sftp->fstatvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + sftp->fstatvfs_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, responses, sftp->fstatvfs_request_id, + &data, &data_len); + + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->fstatvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP EXTENDED REPLY"); + } + + if (data[0] == SSH_FXP_STATUS) { + int retcode = _libssh2_ntohu32(data + 5); + sftp->fstatvfs_state = libssh2_NB_state_idle; + LIBSSH2_FREE(session, data); + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + + if (data_len < 93) { + LIBSSH2_FREE(session, data); + sftp->fstatvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error: short response"); + } + + sftp->fstatvfs_state = libssh2_NB_state_idle; + + st->f_bsize = _libssh2_ntohu64(data + 5); + st->f_frsize = _libssh2_ntohu64(data + 13); + st->f_blocks = _libssh2_ntohu64(data + 21); + st->f_bfree = _libssh2_ntohu64(data + 29); + st->f_bavail = _libssh2_ntohu64(data + 37); + st->f_files = _libssh2_ntohu64(data + 45); + st->f_ffree = _libssh2_ntohu64(data + 53); + st->f_favail = _libssh2_ntohu64(data + 61); + st->f_fsid = _libssh2_ntohu64(data + 69); + flag = (unsigned int)_libssh2_ntohu64(data + 77); + st->f_namemax = _libssh2_ntohu64(data + 85); + + st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY) + ? LIBSSH2_SFTP_ST_RDONLY : 0; + st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID) + ? LIBSSH2_SFTP_ST_NOSUID : 0; + + LIBSSH2_FREE(session, data); + return 0; +} + +/* libssh2_sftp_fstatvfs + * Get filesystem space and inode utilization (requires fstatvfs@openssh.com + * support on the server) + */ +LIBSSH2_API int +libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st) +{ + int rc; + if(!handle || !st) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, handle->sftp->channel->session, sftp_fstatvfs(handle, st)); + return rc; +} + +/* + * sftp_statvfs + * + * Get file system statistics + */ +static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, LIBSSH2_SFTP_STATVFS *st) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 17 = packet_len(4) + packet_type(1) + request_id(4) + ext_len(4) + + path_len (4) */ + /* 19 = strlen ("statvfs@openssh.com") */ + uint32_t packet_len = path_len + 19 + 17; + unsigned char *packet, *s, *data; + ssize_t rc; + unsigned int flag; + static const unsigned char responses[2] = + { SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS }; + + if (sftp->statvfs_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Getting file system statistics of %s", path); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_EXTENDED " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_EXTENDED; + sftp->statvfs_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->statvfs_request_id); + _libssh2_store_str(&s, "statvfs@openssh.com", 19); + _libssh2_store_str(&s, path, path_len); + + sftp->statvfs_state = libssh2_NB_state_created; + } + else { + packet = sftp->statvfs_packet; + } + + if (sftp->statvfs_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN || + (0 <= rc && rc < (ssize_t)packet_len)) { + sftp->statvfs_packet = packet; + return LIBSSH2_ERROR_EAGAIN; + } + + LIBSSH2_FREE(session, packet); + sftp->statvfs_packet = NULL; + + if (rc < 0) { + sftp->statvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + sftp->statvfs_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, responses, sftp->statvfs_request_id, + &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->statvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP EXTENDED REPLY"); + } + + if (data[0] == SSH_FXP_STATUS) { + int retcode = _libssh2_ntohu32(data + 5); + sftp->statvfs_state = libssh2_NB_state_idle; + LIBSSH2_FREE(session, data); + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + + if (data_len < 93) { + LIBSSH2_FREE(session, data); + sftp->statvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error: short response"); + } + + sftp->statvfs_state = libssh2_NB_state_idle; + + st->f_bsize = _libssh2_ntohu64(data + 5); + st->f_frsize = _libssh2_ntohu64(data + 13); + st->f_blocks = _libssh2_ntohu64(data + 21); + st->f_bfree = _libssh2_ntohu64(data + 29); + st->f_bavail = _libssh2_ntohu64(data + 37); + st->f_files = _libssh2_ntohu64(data + 45); + st->f_ffree = _libssh2_ntohu64(data + 53); + st->f_favail = _libssh2_ntohu64(data + 61); + st->f_fsid = _libssh2_ntohu64(data + 69); + flag = (unsigned int)_libssh2_ntohu64(data + 77); + st->f_namemax = _libssh2_ntohu64(data + 85); + + st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY) + ? LIBSSH2_SFTP_ST_RDONLY : 0; + st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID) + ? LIBSSH2_SFTP_ST_NOSUID : 0; + + LIBSSH2_FREE(session, data); + return 0; +} + +/* libssh2_sftp_statvfs_ex + * Get filesystem space and inode utilization (requires statvfs@openssh.com + * support on the server) + */ +LIBSSH2_API int +libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path, + size_t path_len, LIBSSH2_SFTP_STATVFS *st) +{ + int rc; + if(!sftp || !st) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, sftp_statvfs(sftp, path, path_len, + st)); + return rc; +} + + +/* + * sftp_mkdir + * + * Create an SFTP directory + */ +static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, long mode) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_ATTRIBUTES attrs = { + LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 + }; + size_t data_len; + int retcode; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = path_len + 13 + + sftp_attrsize(LIBSSH2_SFTP_ATTR_PERMISSIONS); + unsigned char *packet, *s, *data; + int rc; + + if (sftp->mkdir_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Creating directory %s with mode 0%lo", path, mode); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_MKDIR " + "packet"); + } + /* Filetype in SFTP 3 and earlier */ + attrs.permissions = mode | LIBSSH2_SFTP_ATTR_PFILETYPE_DIR; + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_MKDIR; + sftp->mkdir_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->mkdir_request_id); + _libssh2_store_str(&s, path, path_len); + + s += sftp_attr2bin(s, &attrs); + + sftp->mkdir_state = libssh2_NB_state_created; + } + else { + packet = sftp->mkdir_packet; + } + + if (sftp->mkdir_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + sftp->mkdir_packet = packet; + return rc; + } + if (packet_len != rc) { + LIBSSH2_FREE(session, packet); + sftp->mkdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + LIBSSH2_FREE(session, packet); + sftp->mkdir_state = libssh2_NB_state_sent; + sftp->mkdir_packet = NULL; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->mkdir_request_id, + &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->mkdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->mkdir_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode == LIBSSH2_FX_OK) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "OK!"); + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } +} + +/* + * libssh2_sftp_mkdir_ex + * + * Create an SFTP directory + */ +LIBSSH2_API int +libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, long mode) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_mkdir(sftp, path, path_len, mode)); + return rc; +} + +/* sftp_rmdir + * Remove a directory + */ +static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + int retcode; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = path_len + 13; + unsigned char *s, *data; + int rc; + + if (sftp->rmdir_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Removing directory: %s", + path); + s = sftp->rmdir_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->rmdir_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_RMDIR " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_RMDIR; + sftp->rmdir_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->rmdir_request_id); + _libssh2_store_str(&s, path, path_len); + + sftp->rmdir_state = libssh2_NB_state_created; + } + + if (sftp->rmdir_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->rmdir_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (packet_len != rc) { + LIBSSH2_FREE(session, sftp->rmdir_packet); + sftp->rmdir_packet = NULL; + sftp->rmdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_RMDIR command"); + } + LIBSSH2_FREE(session, sftp->rmdir_packet); + sftp->rmdir_packet = NULL; + + sftp->rmdir_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->rmdir_request_id, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->rmdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->rmdir_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } +} + +/* libssh2_sftp_rmdir_ex + * Remove a directory + */ +LIBSSH2_API int +libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_rmdir(sftp, path, path_len)); + return rc; +} + +/* sftp_stat + * Stat a file or symbolic link + */ +static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, int stat_type, + LIBSSH2_SFTP_ATTRIBUTES * attrs) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = + path_len + 13 + + ((stat_type == + LIBSSH2_SFTP_SETSTAT) ? sftp_attrsize(attrs->flags) : 0); + unsigned char *s, *data; + static const unsigned char stat_responses[2] = + { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + int rc; + + if (sftp->stat_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%s %s", + (stat_type == LIBSSH2_SFTP_SETSTAT) ? "Set-statting" : + (stat_type == + LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path); + s = sftp->stat_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->stat_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_*STAT " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + + switch (stat_type) { + case LIBSSH2_SFTP_SETSTAT: + *(s++) = SSH_FXP_SETSTAT; + break; + + case LIBSSH2_SFTP_LSTAT: + *(s++) = SSH_FXP_LSTAT; + break; + + case LIBSSH2_SFTP_STAT: + default: + *(s++) = SSH_FXP_STAT; + } + sftp->stat_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->stat_request_id); + _libssh2_store_str(&s, path, path_len); + + if (stat_type == LIBSSH2_SFTP_SETSTAT) + s += sftp_attr2bin(s, attrs); + + sftp->stat_state = libssh2_NB_state_created; + } + + if (sftp->stat_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->stat_packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (packet_len != rc) { + LIBSSH2_FREE(session, sftp->stat_packet); + sftp->stat_packet = NULL; + sftp->stat_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send STAT/LSTAT/SETSTAT command"); + } + LIBSSH2_FREE(session, sftp->stat_packet); + sftp->stat_packet = NULL; + + sftp->stat_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, stat_responses, + sftp->stat_request_id, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (rc) { + sftp->stat_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Timeout waiting for status message"); + } + + sftp->stat_state = libssh2_NB_state_idle; + + if (data[0] == SSH_FXP_STATUS) { + int retcode; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + sftp_bin2attr(attrs, data + 5); + LIBSSH2_FREE(session, data); + + return 0; +} + +/* libssh2_sftp_stat_ex + * Stat a file or symbolic link + */ +LIBSSH2_API int +libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, int stat_type, + LIBSSH2_SFTP_ATTRIBUTES *attrs) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_stat(sftp, path, path_len, stat_type, attrs)); + return rc; +} + +/* sftp_symlink + * Read or set a symlink + */ +static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, char *target, + unsigned int target_len, int link_type) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len, link_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = + path_len + 13 + + ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0); + unsigned char *s, *data; + static const unsigned char link_responses[2] = + { SSH_FXP_NAME, SSH_FXP_STATUS }; + int retcode; + + if ((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) { + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Server does not support SYMLINK or READLINK"); + } + + if (sftp->symlink_state == libssh2_NB_state_idle) { + s = sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->symlink_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "SYMLINK/READLINK/REALPATH packet"); + } + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%s %s on %s", + (link_type == + LIBSSH2_SFTP_SYMLINK) ? "Creating" : "Reading", + (link_type == + LIBSSH2_SFTP_REALPATH) ? "realpath" : "symlink", path); + + _libssh2_store_u32(&s, packet_len - 4); + + switch (link_type) { + case LIBSSH2_SFTP_REALPATH: + *(s++) = SSH_FXP_REALPATH; + break; + + case LIBSSH2_SFTP_SYMLINK: + *(s++) = SSH_FXP_SYMLINK; + break; + + case LIBSSH2_SFTP_READLINK: + default: + *(s++) = SSH_FXP_READLINK; + } + sftp->symlink_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->symlink_request_id); + _libssh2_store_str(&s, path, path_len); + + if (link_type == LIBSSH2_SFTP_SYMLINK) + _libssh2_store_str(&s, target, target_len); + + sftp->symlink_state = libssh2_NB_state_created; + } + + if (sftp->symlink_state == libssh2_NB_state_created) { + ssize_t rc = _libssh2_channel_write(channel, 0, sftp->symlink_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (packet_len != rc) { + LIBSSH2_FREE(session, sftp->symlink_packet); + sftp->symlink_packet = NULL; + sftp->symlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send SYMLINK/READLINK command"); + } + LIBSSH2_FREE(session, sftp->symlink_packet); + sftp->symlink_packet = NULL; + + sftp->symlink_state = libssh2_NB_state_sent; + } + + retcode = sftp_packet_requirev(sftp, 2, link_responses, + sftp->symlink_request_id, &data, + &data_len); + if (retcode == LIBSSH2_ERROR_EAGAIN) + return retcode; + else if (retcode) { + sftp->symlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, retcode, + "Error waiting for status message"); + } + + sftp->symlink_state = libssh2_NB_state_idle; + + if (data[0] == SSH_FXP_STATUS) { + int retcode; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_OK) + return LIBSSH2_ERROR_NONE; + else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + if (_libssh2_ntohu32(data + 5) < 1) { + LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Invalid READLINK/REALPATH response, " + "no name entries"); + } + + /* this reads a u32 and stores it into a signed 32bit value */ + link_len = _libssh2_ntohu32(data + 9); + if (link_len < target_len) { + memcpy(target, data + 13, link_len); + target[link_len] = 0; + retcode = (int)link_len; + } + else + retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL; + LIBSSH2_FREE(session, data); + + return retcode; +} + +/* libssh2_sftp_symlink_ex + * Read or set a symlink + */ +LIBSSH2_API int +libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, char *target, + unsigned int target_len, int link_type) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_symlink(sftp, path, path_len, target, target_len, + link_type)); + return rc; +} + +/* libssh2_sftp_last_error + * Returns the last error code reported by SFTP + */ +LIBSSH2_API unsigned long +libssh2_sftp_last_error(LIBSSH2_SFTP *sftp) +{ + if(!sftp) + return 0; + + return sftp->last_errno; +} + +/* libssh2_sftp_get_channel + * Return the channel of sftp, then caller can control the channel's behavior. + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp) +{ + if (!sftp) + return NULL; + + return sftp->channel; +} diff --git a/libssh2/src/sftp.h b/libssh2/src/sftp.h new file mode 100644 index 000000000..2ed32cea6 --- /dev/null +++ b/libssh2/src/sftp.h @@ -0,0 +1,237 @@ +#ifndef _LIBSSH2_SFTP_H +#define _LIBSSH2_SFTP_H +/* + * Copyright (C) 2010 - 2012 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + * + */ + +/* + * MAX_SFTP_OUTGOING_SIZE MUST not be larger than 32500 or so. This is the + * amount of data sent in each FXP_WRITE packet + */ +#define MAX_SFTP_OUTGOING_SIZE 30000 + +/* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ + * packets. + */ +#define MAX_SFTP_READ_SIZE 30000 + +struct sftp_pipeline_chunk { + struct list_node node; + libssh2_uint64_t offset; /* READ: offset at which to start reading + WRITE: not used */ + size_t len; /* WRITE: size of the data to write + READ: how many bytes that was asked for */ + size_t sent; + ssize_t lefttosend; /* if 0, the entire packet has been sent off */ + uint32_t request_id; + unsigned char packet[1]; /* data */ +}; + +struct sftp_zombie_requests { + struct list_node node; + uint32_t request_id; +}; + +#ifndef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +struct _LIBSSH2_SFTP_PACKET +{ + struct list_node node; /* linked list header */ + uint32_t request_id; + unsigned char *data; + size_t data_len; /* payload size */ +}; + +typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET; + +#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */ + +struct _LIBSSH2_SFTP_HANDLE +{ + struct list_node node; + + LIBSSH2_SFTP *sftp; + + char handle[SFTP_HANDLE_MAXLEN]; + size_t handle_len; + + enum { + LIBSSH2_SFTP_HANDLE_FILE, + LIBSSH2_SFTP_HANDLE_DIR + } handle_type; + + union _libssh2_sftp_handle_data + { + struct _libssh2_sftp_handle_file_data + { + libssh2_uint64_t offset; + libssh2_uint64_t offset_sent; + size_t acked; /* container for acked data that hasn't been + returned to caller yet, used for sftp_write */ + + /* 'data' is used by sftp_read() and is allocated data that has + been received already from the server but wasn't returned to + the caller yet. It is of size 'data_len' and 'data_left is the + number of bytes not yet returned, counted from the end of the + buffer. */ + unsigned char *data; + size_t data_len; + size_t data_left; + + char eof; /* we have read to the end */ + } file; + struct _libssh2_sftp_handle_dir_data + { + uint32_t names_left; + void *names_packet; + char *next_name; + } dir; + } u; + + /* State variables used in libssh2_sftp_close_handle() */ + libssh2_nonblocking_states close_state; + uint32_t close_request_id; + unsigned char *close_packet; + + /* list of outstanding packets sent to server */ + struct list_head packet_list; + +}; + +struct _LIBSSH2_SFTP +{ + LIBSSH2_CHANNEL *channel; + + uint32_t request_id, version; + + struct list_head packets; + + /* List of FXP_READ responses to ignore because EOF already received. */ + struct list_head zombie_requests; + + /* a list of _LIBSSH2_SFTP_HANDLE structs */ + struct list_head sftp_handles; + + uint32_t last_errno; + + /* Holder for partial packet, use in libssh2_sftp_packet_read() */ + unsigned char partial_size[4]; /* buffer for size field */ + size_t partial_size_len; /* size field length */ + unsigned char *partial_packet; /* The data */ + uint32_t partial_len; /* Desired number of bytes */ + size_t partial_received; /* Bytes received so far */ + + /* Time that libssh2_sftp_packet_requirev() started reading */ + time_t requirev_start; + + /* State variables used in libssh2_sftp_open_ex() */ + libssh2_nonblocking_states open_state; + unsigned char *open_packet; + uint32_t open_packet_len; /* 32 bit on the wire */ + size_t open_packet_sent; + uint32_t open_request_id; + + /* State variable used in sftp_read() */ + libssh2_nonblocking_states read_state; + + /* State variable used in sftp_packet_read() */ + libssh2_nonblocking_states packet_state; + + /* State variable used in sftp_write() */ + libssh2_nonblocking_states write_state; + + /* State variables used in sftp_fsync() */ + libssh2_nonblocking_states fsync_state; + unsigned char *fsync_packet; + uint32_t fsync_request_id; + + /* State variables used in libssh2_sftp_readdir() */ + libssh2_nonblocking_states readdir_state; + unsigned char *readdir_packet; + uint32_t readdir_request_id; + + /* State variables used in libssh2_sftp_fstat_ex() */ + libssh2_nonblocking_states fstat_state; + unsigned char *fstat_packet; + uint32_t fstat_request_id; + + /* State variables used in libssh2_sftp_unlink_ex() */ + libssh2_nonblocking_states unlink_state; + unsigned char *unlink_packet; + uint32_t unlink_request_id; + + /* State variables used in libssh2_sftp_rename_ex() */ + libssh2_nonblocking_states rename_state; + unsigned char *rename_packet; + unsigned char *rename_s; + uint32_t rename_request_id; + + /* State variables used in libssh2_sftp_fstatvfs() */ + libssh2_nonblocking_states fstatvfs_state; + unsigned char *fstatvfs_packet; + uint32_t fstatvfs_request_id; + + /* State variables used in libssh2_sftp_statvfs() */ + libssh2_nonblocking_states statvfs_state; + unsigned char *statvfs_packet; + uint32_t statvfs_request_id; + + /* State variables used in libssh2_sftp_mkdir() */ + libssh2_nonblocking_states mkdir_state; + unsigned char *mkdir_packet; + uint32_t mkdir_request_id; + + /* State variables used in libssh2_sftp_rmdir() */ + libssh2_nonblocking_states rmdir_state; + unsigned char *rmdir_packet; + uint32_t rmdir_request_id; + + /* State variables used in libssh2_sftp_stat() */ + libssh2_nonblocking_states stat_state; + unsigned char *stat_packet; + uint32_t stat_request_id; + + /* State variables used in libssh2_sftp_symlink() */ + libssh2_nonblocking_states symlink_state; + unsigned char *symlink_packet; + uint32_t symlink_request_id; +}; + +#endif diff --git a/libssh2/src/transport.c b/libssh2/src/transport.c new file mode 100644 index 000000000..8725da095 --- /dev/null +++ b/libssh2/src/transport.c @@ -0,0 +1,891 @@ +/* Copyright (C) 2007 The Written Word, Inc. All rights reserved. + * Copyright (C) 2009-2010 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + * + * This file handles reading and writing to the SECSH transport layer. RFC4253. + */ + +#include "libssh2_priv.h" +#include +#include +#include +#ifdef LIBSSH2DEBUG +#include +#endif + +#include + +#include "transport.h" +#include "mac.h" + +#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */ +#define MAX_MACSIZE 64 /* MUST fit biggest MAC length we support */ + +#ifdef LIBSSH2DEBUG +#define UNPRINTABLE_CHAR '.' +static void +debugdump(LIBSSH2_SESSION * session, + const char *desc, const unsigned char *ptr, size_t size) +{ + size_t i; + size_t c; + unsigned int width = 0x10; + char buffer[256]; /* Must be enough for width*4 + about 30 or so */ + size_t used; + static const char* hex_chars = "0123456789ABCDEF"; + + if (!(session->showmask & LIBSSH2_TRACE_TRANS)) { + /* not asked for, bail out */ + return; + } + + used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n", + desc, (int) size); + if (session->tracehandler) + (session->tracehandler)(session, session->tracehandler_context, + buffer, used); + else + fprintf(stderr, "%s", buffer); + + for(i = 0; i < size; i += width) { + + used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i); + + /* hex not disabled, show it */ + for(c = 0; c < width; c++) { + if (i + c < size) { + buffer[used++] = hex_chars[(ptr[i+c] >> 4) & 0xF]; + buffer[used++] = hex_chars[ptr[i+c] & 0xF]; + } + else { + buffer[used++] = ' '; + buffer[used++] = ' '; + } + + buffer[used++] = ' '; + if ((width/2) - 1 == c) + buffer[used++] = ' '; + } + + buffer[used++] = ':'; + buffer[used++] = ' '; + + for(c = 0; (c < width) && (i + c < size); c++) { + buffer[used++] = isprint(ptr[i + c]) ? + ptr[i + c] : UNPRINTABLE_CHAR; + } + buffer[used++] = '\n'; + buffer[used] = 0; + + if (session->tracehandler) + (session->tracehandler)(session, session->tracehandler_context, + buffer, used); + else + fprintf(stderr, "%s", buffer); + } +} +#else +#define debugdump(a,x,y,z) +#endif + + +/* decrypt() decrypts 'len' bytes from 'source' to 'dest'. + * + * returns 0 on success and negative on failure + */ + +static int +decrypt(LIBSSH2_SESSION * session, unsigned char *source, + unsigned char *dest, int len) +{ + struct transportpacket *p = &session->packet; + int blocksize = session->remote.crypt->blocksize; + + /* if we get called with a len that isn't an even number of blocksizes + we risk losing those extra bytes */ + assert((len % blocksize) == 0); + + while (len >= blocksize) { + if (session->remote.crypt->crypt(session, source, blocksize, + &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, p->payload); + return LIBSSH2_ERROR_DECRYPT; + } + + /* if the crypt() function would write to a given address it + wouldn't have to memcpy() and we could avoid this memcpy() + too */ + memcpy(dest, source, blocksize); + + len -= blocksize; /* less bytes left */ + dest += blocksize; /* advance write pointer */ + source += blocksize; /* advance read pointer */ + } + return LIBSSH2_ERROR_NONE; /* all is fine */ +} + +/* + * fullpacket() gets called when a full packet has been received and properly + * collected. + */ +static int +fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) +{ + unsigned char macbuf[MAX_MACSIZE]; + struct transportpacket *p = &session->packet; + int rc; + int compressed; + + if (session->fullpacket_state == libssh2_NB_state_idle) { + session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; + session->fullpacket_payload_len = p->packet_length - 1; + + if (encrypted) { + + /* Calculate MAC hash */ + session->remote.mac->hash(session, macbuf, /* store hash here */ + session->remote.seqno, + p->init, 5, + p->payload, + session->fullpacket_payload_len, + &session->remote.mac_abstract); + + /* Compare the calculated hash with the MAC we just read from + * the network. The read one is at the very end of the payload + * buffer. Note that 'payload_len' here is the packet_length + * field which includes the padding but not the MAC. + */ + if (memcmp(macbuf, p->payload + session->fullpacket_payload_len, + session->remote.mac->mac_len)) { + session->fullpacket_macstate = LIBSSH2_MAC_INVALID; + } + } + + session->remote.seqno++; + + /* ignore the padding */ + session->fullpacket_payload_len -= p->padding_length; + + /* Check for and deal with decompression */ + compressed = + session->local.comp != NULL && + session->local.comp->compress && + ((session->state & LIBSSH2_STATE_AUTHENTICATED) || + session->local.comp->use_in_auth); + + if (compressed && session->remote.comp_abstract) { + /* + * The buffer for the decompression (remote.comp_abstract) is + * initialised in time when it is needed so as long it is NULL we + * cannot decompress. + */ + + unsigned char *data; + size_t data_len; + rc = session->remote.comp->decomp(session, + &data, &data_len, + LIBSSH2_PACKET_MAXDECOMP, + p->payload, + session->fullpacket_payload_len, + &session->remote.comp_abstract); + LIBSSH2_FREE(session, p->payload); + if(rc) + return rc; + + p->payload = data; + session->fullpacket_payload_len = data_len; + } + + session->fullpacket_packet_type = p->payload[0]; + + debugdump(session, "libssh2_transport_read() plain", + p->payload, session->fullpacket_payload_len); + + session->fullpacket_state = libssh2_NB_state_created; + } + + if (session->fullpacket_state == libssh2_NB_state_created) { + rc = _libssh2_packet_add(session, p->payload, + session->fullpacket_payload_len, + session->fullpacket_macstate); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + if (rc) { + session->fullpacket_state = libssh2_NB_state_idle; + return rc; + } + } + + session->fullpacket_state = libssh2_NB_state_idle; + + return session->fullpacket_packet_type; +} + + +/* + * _libssh2_transport_read + * + * Collect a packet into the input queue. + * + * Returns packet type added to input queue (0 if nothing added), or a + * negative error number. + */ + +/* + * This function reads the binary stream as specified in chapter 6 of RFC4253 + * "The Secure Shell (SSH) Transport Layer Protocol" + * + * DOES NOT call _libssh2_error() for ANY error case. + */ +int _libssh2_transport_read(LIBSSH2_SESSION * session) +{ + int rc; + struct transportpacket *p = &session->packet; + int remainbuf; + int remainpack; + int numbytes; + int numdecrypt; + unsigned char block[MAX_BLOCKSIZE]; + int blocksize; + int encrypted = 1; + size_t total_num; + + /* default clear the bit */ + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; + + /* + * All channels, systems, subsystems, etc eventually make it down here + * when looking for more incoming data. If a key exchange is going on + * (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will + * ONLY send key exchange related traffic. In non-blocking mode, there is + * a chance to break out of the kex_exchange function with an EAGAIN + * status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is + * active, then we must redirect to the key exchange. However, if + * kex_exchange is active (as in it is the one that calls this execution + * of packet_read, then don't redirect, as that would be an infinite loop! + */ + + if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS && + !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { + + /* Whoever wants a packet won't get anything until the key re-exchange + * is done! + */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the" + " key re-exchange from _libssh2_transport_read"); + rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); + if (rc) + return rc; + } + + /* + * =============================== NOTE =============================== + * I know this is very ugly and not a really good use of "goto", but + * this case statement would be even uglier to do it any other way + */ + if (session->readPack_state == libssh2_NB_state_jump1) { + session->readPack_state = libssh2_NB_state_idle; + encrypted = session->readPack_encrypted; + goto libssh2_transport_read_point1; + } + + do { + if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { + return LIBSSH2_ERROR_NONE; + } + + if (session->state & LIBSSH2_STATE_NEWKEYS) { + blocksize = session->remote.crypt->blocksize; + } else { + encrypted = 0; /* not encrypted */ + blocksize = 5; /* not strictly true, but we can use 5 here to + make the checks below work fine still */ + } + + /* read/use a whole big chunk into a temporary area stored in + the LIBSSH2_SESSION struct. We will decrypt data from that + buffer into the packet buffer so this temp one doesn't have + to be able to keep a whole SSH packet, just be large enough + so that we can read big chunks from the network layer. */ + + /* how much data there is remaining in the buffer to deal with + before we should read more from the network */ + remainbuf = p->writeidx - p->readidx; + + /* if remainbuf turns negative we have a bad internal error */ + assert(remainbuf >= 0); + + if (remainbuf < blocksize) { + /* If we have less than a blocksize left, it is too + little data to deal with, read more */ + ssize_t nread; + + /* move any remainder to the start of the buffer so + that we can do a full refill */ + if (remainbuf) { + memmove(p->buf, &p->buf[p->readidx], remainbuf); + p->readidx = 0; + p->writeidx = remainbuf; + } else { + /* nothing to move, just zero the indexes */ + p->readidx = p->writeidx = 0; + } + + /* now read a big chunk from the network into the temp buffer */ + nread = + LIBSSH2_RECV(session, &p->buf[remainbuf], + PACKETBUFSIZE - remainbuf, + LIBSSH2_SOCKET_RECV_FLAGS(session)); + if (nread <= 0) { + /* check if this is due to EAGAIN and return the special + return code if so, error out normally otherwise */ + if ((nread < 0) && (nread == -EAGAIN)) { + session->socket_block_directions |= + LIBSSH2_SESSION_BLOCK_INBOUND; + return LIBSSH2_ERROR_EAGAIN; + } + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error recving %d bytes (got %d)", + PACKETBUFSIZE - remainbuf, -nread); + return LIBSSH2_ERROR_SOCKET_RECV; + } + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Recved %d/%d bytes to %p+%d", nread, + PACKETBUFSIZE - remainbuf, p->buf, remainbuf); + + debugdump(session, "libssh2_transport_read() raw", + &p->buf[remainbuf], nread); + /* advance write pointer */ + p->writeidx += nread; + + /* update remainbuf counter */ + remainbuf = p->writeidx - p->readidx; + } + + /* how much data to deal with from the buffer */ + numbytes = remainbuf; + + if (!p->total_num) { + /* No payload package area allocated yet. To know the + size of this payload, we need to decrypt the first + blocksize data. */ + + if (numbytes < blocksize) { + /* we can't act on anything less than blocksize, but this + check is only done for the initial block since once we have + got the start of a block we can in fact deal with fractions + */ + session->socket_block_directions |= + LIBSSH2_SESSION_BLOCK_INBOUND; + return LIBSSH2_ERROR_EAGAIN; + } + + if (encrypted) { + rc = decrypt(session, &p->buf[p->readidx], block, blocksize); + if (rc != LIBSSH2_ERROR_NONE) { + return rc; + } + /* save the first 5 bytes of the decrypted package, to be + used in the hash calculation later down. */ + memcpy(p->init, &p->buf[p->readidx], 5); + } else { + /* the data is plain, just copy it verbatim to + the working block buffer */ + memcpy(block, &p->buf[p->readidx], blocksize); + } + + /* advance the read pointer */ + p->readidx += blocksize; + + /* we now have the initial blocksize bytes decrypted, + * and we can extract packet and padding length from it + */ + p->packet_length = _libssh2_ntohu32(block); + if (p->packet_length < 1) + return LIBSSH2_ERROR_DECRYPT; + + p->padding_length = block[4]; + + /* total_num is the number of bytes following the initial + (5 bytes) packet length and padding length fields */ + total_num = + p->packet_length - 1 + + (encrypted ? session->remote.mac->mac_len : 0); + + /* RFC4253 section 6.1 Maximum Packet Length says: + * + * "All implementations MUST be able to process + * packets with uncompressed payload length of 32768 + * bytes or less and total packet size of 35000 bytes + * or less (including length, padding length, payload, + * padding, and MAC.)." + */ + if (total_num > LIBSSH2_PACKET_MAXPAYLOAD) { + return LIBSSH2_ERROR_OUT_OF_BOUNDARY; + } + + /* Get a packet handle put data into. We get one to + hold all data, including padding and MAC. */ + p->payload = LIBSSH2_ALLOC(session, total_num); + if (!p->payload) { + return LIBSSH2_ERROR_ALLOC; + } + p->total_num = total_num; + /* init write pointer to start of payload buffer */ + p->wptr = p->payload; + + if (blocksize > 5) { + /* copy the data from index 5 to the end of + the blocksize from the temporary buffer to + the start of the decrypted buffer */ + memcpy(p->wptr, &block[5], blocksize - 5); + p->wptr += blocksize - 5; /* advance write pointer */ + } + + /* init the data_num field to the number of bytes of + the package read so far */ + p->data_num = p->wptr - p->payload; + + /* we already dealt with a blocksize worth of data */ + numbytes -= blocksize; + } + + /* how much there is left to add to the current payload + package */ + remainpack = p->total_num - p->data_num; + + if (numbytes > remainpack) { + /* if we have more data in the buffer than what is going into this + particular packet, we limit this round to this packet only */ + numbytes = remainpack; + } + + if (encrypted) { + /* At the end of the incoming stream, there is a MAC, + and we don't want to decrypt that since we need it + "raw". We MUST however decrypt the padding data + since it is used for the hash later on. */ + int skip = session->remote.mac->mac_len; + + /* if what we have plus numbytes is bigger than the + total minus the skip margin, we should lower the + amount to decrypt even more */ + if ((p->data_num + numbytes) > (p->total_num - skip)) { + numdecrypt = (p->total_num - skip) - p->data_num; + } else { + int frac; + numdecrypt = numbytes; + frac = numdecrypt % blocksize; + if (frac) { + /* not an aligned amount of blocks, + align it */ + numdecrypt -= frac; + /* and make it no unencrypted data + after it */ + numbytes = 0; + } + } + } else { + /* unencrypted data should not be decrypted at all */ + numdecrypt = 0; + } + + /* if there are bytes to decrypt, do that */ + if (numdecrypt > 0) { + /* now decrypt the lot */ + rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt); + if (rc != LIBSSH2_ERROR_NONE) { + p->total_num = 0; /* no packet buffer available */ + return rc; + } + + /* advance the read pointer */ + p->readidx += numdecrypt; + /* advance write pointer */ + p->wptr += numdecrypt; + /* increase data_num */ + p->data_num += numdecrypt; + + /* bytes left to take care of without decryption */ + numbytes -= numdecrypt; + } + + /* if there are bytes to copy that aren't decrypted, simply + copy them as-is to the target buffer */ + if (numbytes > 0) { + memcpy(p->wptr, &p->buf[p->readidx], numbytes); + + /* advance the read pointer */ + p->readidx += numbytes; + /* advance write pointer */ + p->wptr += numbytes; + /* increase data_num */ + p->data_num += numbytes; + } + + /* now check how much data there's left to read to finish the + current packet */ + remainpack = p->total_num - p->data_num; + + if (!remainpack) { + /* we have a full packet */ + libssh2_transport_read_point1: + rc = fullpacket(session, encrypted); + if (rc == LIBSSH2_ERROR_EAGAIN) { + + if (session->packAdd_state != libssh2_NB_state_idle) + { + /* fullpacket only returns LIBSSH2_ERROR_EAGAIN if + * libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If that + * returns LIBSSH2_ERROR_EAGAIN but the packAdd_state is idle, + * then the packet has been added to the brigade, but some + * immediate action that was taken based on the packet + * type (such as key re-exchange) is not yet complete. + * Clear the way for a new packet to be read in. + */ + session->readPack_encrypted = encrypted; + session->readPack_state = libssh2_NB_state_jump1; + } + + return rc; + } + + p->total_num = 0; /* no packet buffer available */ + + return rc; + } + } while (1); /* loop */ + + return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */ +} + +static int +send_existing(LIBSSH2_SESSION *session, const unsigned char *data, + size_t data_len, ssize_t *ret) +{ + ssize_t rc; + ssize_t length; + struct transportpacket *p = &session->packet; + + if (!p->olen) { + *ret = 0; + return LIBSSH2_ERROR_NONE; + } + + /* send as much as possible of the existing packet */ + if ((data != p->odata) || (data_len != p->olen)) { + /* When we are about to complete the sending of a packet, it is vital + that the caller doesn't try to send a new/different packet since + we don't add this one up until the previous one has been sent. To + make the caller really notice his/hers flaw, we return error for + this case */ + return LIBSSH2_ERROR_BAD_USE; + } + + *ret = 1; /* set to make our parent return */ + + /* number of bytes left to send */ + length = p->ototal_num - p->osent; + + rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if (rc < 0) + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error sending %d bytes: %d", length, -rc); + else { + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Sent %d/%d bytes at %p+%d", rc, length, p->outbuf, + p->osent); + debugdump(session, "libssh2_transport_write send()", + &p->outbuf[p->osent], rc); + } + + if (rc == length) { + /* the remainder of the package was sent */ + p->ototal_num = 0; + p->olen = 0; + /* we leave *ret set so that the parent returns as we MUST return back + a send success now, so that we don't risk sending EAGAIN later + which then would confuse the parent function */ + return LIBSSH2_ERROR_NONE; + + } + else if (rc < 0) { + /* nothing was sent */ + if (rc != -EAGAIN) + /* send failure! */ + return LIBSSH2_ERROR_SOCKET_SEND; + + session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; + return LIBSSH2_ERROR_EAGAIN; + } + + p->osent += rc; /* we sent away this much data */ + + return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE; +} + +/* + * libssh2_transport_send + * + * Send a packet, encrypting it and adding a MAC code if necessary + * Returns 0 on success, non-zero on failure. + * + * The data is provided as _two_ data areas that are combined by this + * function. The 'data' part is sent immediately before 'data2'. 'data2' may + * be set to NULL to only use a single part. + * + * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was + * not sent yet. If it does so, the caller should call this function again as + * soon as it is likely that more data can be sent, and this function MUST + * then be called with the same argument set (same data pointer and same + * data_len) until ERROR_NONE or failure is returned. + * + * This function DOES NOT call _libssh2_error() on any errors. + */ +int _libssh2_transport_send(LIBSSH2_SESSION *session, + const unsigned char *data, size_t data_len, + const unsigned char *data2, size_t data2_len) +{ + int blocksize = + (session->state & LIBSSH2_STATE_NEWKEYS) ? + session->local.crypt->blocksize : 8; + int padding_length; + size_t packet_length; + int total_length; +#ifdef RANDOM_PADDING + int rand_max; + int seed = data[0]; /* FIXME: make this random */ +#endif + struct transportpacket *p = &session->packet; + int encrypted; + int compressed; + ssize_t ret; + int rc; + const unsigned char *orgdata = data; + size_t orgdata_len = data_len; + + /* + * If the last read operation was interrupted in the middle of a key + * exchange, we must complete that key exchange before continuing to write + * further data. + * + * See the similar block in _libssh2_transport_read for more details. + */ + if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS && + !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { + /* Don't write any new packets if we're still in the middle of a key + * exchange. */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the" + " key re-exchange from _libssh2_transport_send"); + rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); + if (rc) + return rc; + } + + debugdump(session, "libssh2_transport_write plain", data, data_len); + if(data2) + debugdump(session, "libssh2_transport_write plain2", data2, data2_len); + + /* FIRST, check if we have a pending write to complete. send_existing + only sanity-check data and data_len and not data2 and data2_len!! */ + rc = send_existing(session, data, data_len, &ret); + if (rc) + return rc; + + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; + + if (ret) + /* set by send_existing if data was sent */ + return rc; + + encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0; + + compressed = + session->local.comp != NULL && + session->local.comp->compress && + ((session->state & LIBSSH2_STATE_AUTHENTICATED) || + session->local.comp->use_in_auth); + + if (encrypted && compressed) { + /* the idea here is that these function must fail if the output gets + larger than what fits in the assigned buffer so thus they don't + check the input size as we don't know how much it compresses */ + size_t dest_len = MAX_SSH_PACKET_LEN-5-256; + size_t dest2_len = dest_len; + + /* compress directly to the target buffer */ + rc = session->local.comp->comp(session, + &p->outbuf[5], &dest_len, + data, data_len, + &session->local.comp_abstract); + if(rc) + return rc; /* compression failure */ + + if(data2 && data2_len) { + /* compress directly to the target buffer right after where the + previous call put data */ + dest2_len -= dest_len; + + rc = session->local.comp->comp(session, + &p->outbuf[5+dest_len], &dest2_len, + data2, data2_len, + &session->local.comp_abstract); + } + else + dest2_len = 0; + if(rc) + return rc; /* compression failure */ + + data_len = dest_len + dest2_len; /* use the combined length */ + } + else { + if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100)) + /* too large packet, return error for this until we make this + function split it up and send multiple SSH packets */ + return LIBSSH2_ERROR_INVAL; + + /* copy the payload data */ + memcpy(&p->outbuf[5], data, data_len); + if(data2 && data2_len) + memcpy(&p->outbuf[5+data_len], data2, data2_len); + data_len += data2_len; /* use the combined length */ + } + + + /* RFC4253 says: Note that the length of the concatenation of + 'packet_length', 'padding_length', 'payload', and 'random padding' + MUST be a multiple of the cipher block size or 8, whichever is + larger. */ + + /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */ + + packet_length = data_len + 1 + 4; /* 1 is for padding_length field + 4 for the packet_length field */ + + /* at this point we have it all except the padding */ + + /* first figure out our minimum padding amount to make it an even + block size */ + padding_length = blocksize - (packet_length % blocksize); + + /* if the padding becomes too small we add another blocksize worth + of it (taken from the original libssh2 where it didn't have any + real explanation) */ + if (padding_length < 4) { + padding_length += blocksize; + } +#ifdef RANDOM_PADDING + /* FIXME: we can add padding here, but that also makes the packets + bigger etc */ + + /* now we can add 'blocksize' to the padding_length N number of times + (to "help thwart traffic analysis") but it must be less than 255 in + total */ + rand_max = (255 - padding_length) / blocksize + 1; + padding_length += blocksize * (seed % rand_max); +#endif + + packet_length += padding_length; + + /* append the MAC length to the total_length size */ + total_length = + packet_length + (encrypted ? session->local.mac->mac_len : 0); + + /* store packet_length, which is the size of the whole packet except + the MAC and the packet_length field itself */ + _libssh2_htonu32(p->outbuf, packet_length - 4); + /* store padding_length */ + p->outbuf[4] = (unsigned char)padding_length; + + /* fill the padding area with random junk */ + _libssh2_random(p->outbuf + 5 + data_len, padding_length); + + if (encrypted) { + size_t i; + + /* Calculate MAC hash. Put the output at index packet_length, + since that size includes the whole packet. The MAC is + calculated on the entire unencrypted packet, including all + fields except the MAC field itself. */ + session->local.mac->hash(session, p->outbuf + packet_length, + session->local.seqno, p->outbuf, + packet_length, NULL, 0, + &session->local.mac_abstract); + + /* Encrypt the whole packet data, one block size at a time. + The MAC field is not encrypted. */ + for(i = 0; i < packet_length; i += session->local.crypt->blocksize) { + unsigned char *ptr = &p->outbuf[i]; + if (session->local.crypt->crypt(session, ptr, + session->local.crypt->blocksize, + &session->local.crypt_abstract)) + return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */ + } + } + + session->local.seqno++; + + ret = LIBSSH2_SEND(session, p->outbuf, total_length, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if (ret < 0) + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error sending %d bytes: %d", total_length, -ret); + else { + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p", + ret, total_length, p->outbuf); + debugdump(session, "libssh2_transport_write send()", p->outbuf, ret); + } + + if (ret != total_length) { + if (ret >= 0 || ret == -EAGAIN) { + /* the whole packet could not be sent, save the rest */ + session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; + p->odata = orgdata; + p->olen = orgdata_len; + p->osent = ret <= 0 ? 0 : ret; + p->ototal_num = total_length; + return LIBSSH2_ERROR_EAGAIN; + } + return LIBSSH2_ERROR_SOCKET_SEND; + } + + /* the whole thing got sent away */ + p->odata = NULL; + p->olen = 0; + + return LIBSSH2_ERROR_NONE; /* all is good */ +} diff --git a/libssh2/src/transport.h b/libssh2/src/transport.h new file mode 100644 index 000000000..89982a67f --- /dev/null +++ b/libssh2/src/transport.h @@ -0,0 +1,87 @@ +#ifndef __LIBSSH2_TRANSPORT_H +#define __LIBSSH2_TRANSPORT_H + +/* Copyright (C) 2007 The Written Word, Inc. All rights reserved. + * Copyright (C) 2009-2010 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + * + * This file handles reading and writing to the SECSH transport layer. RFC4253. + */ + +#include "libssh2_priv.h" +#include "packet.h" + + +/* + * libssh2_transport_send + * + * Send a packet, encrypting it and adding a MAC code if necessary + * Returns 0 on success, non-zero on failure. + * + * The data is provided as _two_ data areas that are combined by this + * function. The 'data' part is sent immediately before 'data2'. 'data2' can + * be set to NULL (or data2_len to 0) to only use a single part. + * + * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was + * not sent yet. If it does so, the caller should call this function again as + * soon as it is likely that more data can be sent, and this function MUST + * then be called with the same argument set (same data pointer and same + * data_len) until ERROR_NONE or failure is returned. + * + * This function DOES NOT call _libssh2_error() on any errors. + */ +int _libssh2_transport_send(LIBSSH2_SESSION *session, + const unsigned char *data, size_t data_len, + const unsigned char *data2, size_t data2_len); + +/* + * _libssh2_transport_read + * + * Collect a packet into the input brigade block only controls whether or not + * to wait for a packet to start. + * + * Returns packet type added to input brigade (PACKET_NONE if nothing added), + * or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full + * packet. + */ + +/* + * This function reads the binary stream as specified in chapter 6 of RFC4253 + * "The Secure Shell (SSH) Transport Layer Protocol" + */ +int _libssh2_transport_read(LIBSSH2_SESSION * session); + +#endif /* __LIBSSH2_TRANSPORT_H */ diff --git a/libssh2/src/userauth.c b/libssh2/src/userauth.c new file mode 100644 index 000000000..cdfa25e66 --- /dev/null +++ b/libssh2/src/userauth.c @@ -0,0 +1,1917 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2005 Mikhail Gusarov + * Copyright (c) 2009-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#include +#include + +#include + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#include "transport.h" +#include "session.h" +#include "userauth.h" + +/* libssh2_userauth_list + * + * List authentication methods + * Will yield successful login if "none" happens to be allowable for this user + * Not a common configuration for any SSH server though + * username should be NULL, or a null terminated string + */ +static char *userauth_list(LIBSSH2_SESSION *session, const char *username, + unsigned int username_len) +{ + static const unsigned char reply_codes[3] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; + /* packet_type(1) + username_len(4) + service_len(4) + + service(14)"ssh-connection" + method_len(4) = 27 */ + unsigned long methods_len; + unsigned char *s; + int rc; + + if (session->userauth_list_state == libssh2_NB_state_idle) { + /* Zero the whole thing out */ + memset(&session->userauth_list_packet_requirev_state, 0, + sizeof(session->userauth_list_packet_requirev_state)); + + session->userauth_list_data_len = username_len + 27; + + s = session->userauth_list_data = + LIBSSH2_ALLOC(session, session->userauth_list_data_len); + if (!session->userauth_list_data) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for userauth_list"); + return NULL; + } + + *(s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", 14); + _libssh2_store_u32(&s, 4); /* send "none" separately */ + + session->userauth_list_state = libssh2_NB_state_created; + } + + if (session->userauth_list_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_list_data, + session->userauth_list_data_len, + (unsigned char *)"none", 4); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list"); + return NULL; + } + /* now free the packet that was sent */ + LIBSSH2_FREE(session, session->userauth_list_data); + session->userauth_list_data = NULL; + + if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-none request"); + session->userauth_list_state = libssh2_NB_state_idle; + return NULL; + } + + session->userauth_list_state = libssh2_NB_state_sent; + } + + if (session->userauth_list_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_list_data, + &session->userauth_list_data_len, 0, + NULL, 0, + &session->userauth_list_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list"); + return NULL; + } else if (rc) { + _libssh2_error(session, rc, "Failed getting response"); + session->userauth_list_state = libssh2_NB_state_idle; + return NULL; + } + + if (session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + /* Wow, who'dve thought... */ + _libssh2_error(session, LIBSSH2_ERROR_NONE, "No error"); + LIBSSH2_FREE(session, session->userauth_list_data); + session->userauth_list_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_list_state = libssh2_NB_state_idle; + return NULL; + } + + methods_len = _libssh2_ntohu32(session->userauth_list_data + 1); + + /* Do note that the memory areas overlap! */ + memmove(session->userauth_list_data, session->userauth_list_data + 5, + methods_len); + session->userauth_list_data[methods_len] = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Permitted auth methods: %s", + session->userauth_list_data); + } + + session->userauth_list_state = libssh2_NB_state_idle; + return (char *) session->userauth_list_data; +} + +/* libssh2_userauth_list + * + * List authentication methods + * Will yield successful login if "none" happens to be allowable for this user + * Not a common configuration for any SSH server though + * username should be NULL, or a null terminated string + */ +LIBSSH2_API char * +libssh2_userauth_list(LIBSSH2_SESSION * session, const char *user, + unsigned int user_len) +{ + char *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, + userauth_list(session, user, user_len)); + return ptr; +} + +/* + * libssh2_userauth_authenticated + * + * Returns: 0 if not yet authenticated + * 1 if already authenticated + */ +LIBSSH2_API int +libssh2_userauth_authenticated(LIBSSH2_SESSION * session) +{ + return (session->state & LIBSSH2_STATE_AUTHENTICATED)?1:0; +} + + + +/* userauth_password + * Plain ol' login + */ +static int +userauth_password(LIBSSH2_SESSION *session, + const char *username, unsigned int username_len, + const unsigned char *password, unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) +{ + unsigned char *s; + static const unsigned char reply_codes[4] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 + }; + int rc; + + if (session->userauth_pswd_state == libssh2_NB_state_idle) { + /* Zero the whole thing out */ + memset(&session->userauth_pswd_packet_requirev_state, 0, + sizeof(session->userauth_pswd_packet_requirev_state)); + + /* + * 40 = packet_type(1) + username_len(4) + service_len(4) + + * service(14)"ssh-connection" + method_len(4) + method(8)"password" + + * chgpwdbool(1) + password_len(4) */ + session->userauth_pswd_data_len = username_len + 40; + + session->userauth_pswd_data0 = + (unsigned char) ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; + + /* TODO: remove this alloc with a fixed buffer in the session + struct */ + s = session->userauth_pswd_data = + LIBSSH2_ALLOC(session, session->userauth_pswd_data_len); + if (!session->userauth_pswd_data) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "userauth-password request"); + } + + *(s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1); + _libssh2_store_str(&s, "password", sizeof("password") - 1); + *s++ = '\0'; + _libssh2_store_u32(&s, password_len); + /* 'password' is sent separately */ + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting to login using password authentication"); + + session->userauth_pswd_state = libssh2_NB_state_created; + } + + if (session->userauth_pswd_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_pswd_data, + session->userauth_pswd_data_len, + password, password_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block writing password request"); + } + + /* now free the sent packet */ + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + + if (rc) { + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-password request"); + } + + session->userauth_pswd_state = libssh2_NB_state_sent; + } + + password_response: + + if ((session->userauth_pswd_state == libssh2_NB_state_sent) + || (session->userauth_pswd_state == libssh2_NB_state_sent1) + || (session->userauth_pswd_state == libssh2_NB_state_sent2)) { + if (session->userauth_pswd_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_pswd_data, + &session->userauth_pswd_data_len, + 0, NULL, 0, + &session-> + userauth_pswd_packet_requirev_state); + + if (rc) { + if (rc != LIBSSH2_ERROR_EAGAIN) + session->userauth_pswd_state = libssh2_NB_state_idle; + + return _libssh2_error(session, rc, + "Waiting for password response"); + } + + if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Password authentication successful"); + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_pswd_state = libssh2_NB_state_idle; + return 0; + } else if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_FAILURE) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Password authentication failed"); + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, + LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Authentication failed " + "(username/password)"); + } + + session->userauth_pswd_newpw = NULL; + session->userauth_pswd_newpw_len = 0; + + session->userauth_pswd_state = libssh2_NB_state_sent1; + } + + if ((session->userauth_pswd_data[0] == + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) + || (session->userauth_pswd_data0 == + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)) { + session->userauth_pswd_data0 = SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; + + if ((session->userauth_pswd_state == libssh2_NB_state_sent1) || + (session->userauth_pswd_state == libssh2_NB_state_sent2)) { + if (session->userauth_pswd_state == libssh2_NB_state_sent1) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Password change required"); + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + } + if (passwd_change_cb) { + if (session->userauth_pswd_state == libssh2_NB_state_sent1) { + passwd_change_cb(session, + &session->userauth_pswd_newpw, + &session->userauth_pswd_newpw_len, + &session->abstract); + if (!session->userauth_pswd_newpw) { + return _libssh2_error(session, + LIBSSH2_ERROR_PASSWORD_EXPIRED, + "Password expired, and " + "callback failed"); + } + + /* basic data_len + newpw_len(4) */ + session->userauth_pswd_data_len = + username_len + password_len + 44; + + s = session->userauth_pswd_data = + LIBSSH2_ALLOC(session, + session->userauth_pswd_data_len); + if (!session->userauth_pswd_data) { + LIBSSH2_FREE(session, + session->userauth_pswd_newpw); + session->userauth_pswd_newpw = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for userauth password " + "change request"); + } + + *(s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", + sizeof("ssh-connection") - 1); + _libssh2_store_str(&s, "password", + sizeof("password") - 1); + *s++ = 0x01; + _libssh2_store_str(&s, (char *)password, password_len); + _libssh2_store_u32(&s, + session->userauth_pswd_newpw_len); + /* send session->userauth_pswd_newpw separately */ + + session->userauth_pswd_state = libssh2_NB_state_sent2; + } + + if (session->userauth_pswd_state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, + session->userauth_pswd_data, + session->userauth_pswd_data_len, + (unsigned char *) + session->userauth_pswd_newpw, + session->userauth_pswd_newpw_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting"); + } + + /* free the allocated packets again */ + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + LIBSSH2_FREE(session, session->userauth_pswd_newpw); + session->userauth_pswd_newpw = NULL; + + if (rc) { + return _libssh2_error(session, + LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth " + "password-change request"); + } + + /* + * Ugliest use of goto ever. Blame it on the + * askN => requirev migration. + */ + session->userauth_pswd_state = libssh2_NB_state_sent; + goto password_response; + } + } + } else { + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, + "Password Expired, and no callback " + "specified"); + } + } + } + + /* FAILURE */ + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + session->userauth_pswd_state = libssh2_NB_state_idle; + + return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Authentication failed"); +} + +/* + * libssh2_userauth_password_ex + * + * Plain ol' login + */ + +LIBSSH2_API int +libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, + unsigned int username_len, const char *password, + unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) +{ + int rc; + BLOCK_ADJUST(rc, session, + userauth_password(session, username, username_len, + (unsigned char *)password, password_len, + passwd_change_cb)); + return rc; +} + +static int +memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *pubkeyfiledata, + size_t pubkeyfiledata_len) +{ + unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; + size_t pubkey_len = pubkeyfiledata_len; + unsigned int tmp_len; + + if (pubkeyfiledata_len <= 1) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid data in public key file"); + } + + pubkey = LIBSSH2_ALLOC(session, pubkeyfiledata_len); + if (!pubkey) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for public key data"); + } + + memcpy(pubkey, pubkeyfiledata, pubkeyfiledata_len); + + /* + * Remove trailing whitespace + */ + while (pubkey_len && isspace(pubkey[pubkey_len - 1])) + pubkey_len--; + + if (!pubkey_len) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Missing public key data"); + } + + if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid public key data"); + } + + sp1++; + + if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) { + /* Assume that the id string is missing, but that it's okay */ + sp2 = pubkey + pubkey_len; + } + + if (libssh2_base64_decode(session, (char **) &tmp, &tmp_len, + (char *) sp1, sp2 - sp1)) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid key data, not base64 encoded"); + } + + /* Wasting some bytes here (okay, more than some), but since it's likely + * to be freed soon anyway, we'll just avoid the extra free/alloc and call + * it a wash + */ + *method = pubkey; + *method_len = sp1 - pubkey - 1; + + *pubkeydata = tmp; + *pubkeydata_len = tmp_len; + + return 0; +} + +/* + * file_read_publickey + * + * Read a public key from an id_???.pub style file + * + * Returns an allocated string containing the decoded key in *pubkeydata + * on success. + * Returns an allocated string containing the key method (e.g. "ssh-dss") + * in method on success. + */ +static int +file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *pubkeyfile) +{ + FILE *fd; + char c; + unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; + size_t pubkey_len = 0, sp_len; + unsigned int tmp_len; + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s", + pubkeyfile); + /* Read Public Key */ + fd = fopen(pubkeyfile, "r"); + if (!fd) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to open public key file"); + } + while (!feof(fd) && 1 == fread(&c, 1, 1, fd) && c != '\r' && c != '\n') { + pubkey_len++; + } + rewind(fd); + + if (pubkey_len <= 1) { + fclose(fd); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid data in public key file"); + } + + pubkey = LIBSSH2_ALLOC(session, pubkey_len); + if (!pubkey) { + fclose(fd); + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for public key data"); + } + if (fread(pubkey, 1, pubkey_len, fd) != pubkey_len) { + LIBSSH2_FREE(session, pubkey); + fclose(fd); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to read public key from file"); + } + fclose(fd); + /* + * Remove trailing whitespace + */ + while (pubkey_len && isspace(pubkey[pubkey_len - 1])) { + pubkey_len--; + } + + if (!pubkey_len) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Missing public key data"); + } + + if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid public key data"); + } + + sp1++; + + sp_len = sp1 > pubkey ? (sp1 - pubkey) - 1 : 0; + if ((sp2 = memchr(sp1, ' ', pubkey_len - sp_len)) == NULL) { + /* Assume that the id string is missing, but that it's okay */ + sp2 = pubkey + pubkey_len; + } + + if (libssh2_base64_decode(session, (char **) &tmp, &tmp_len, + (char *) sp1, sp2 - sp1)) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid key data, not base64 encoded"); + } + + /* Wasting some bytes here (okay, more than some), but since it's likely + * to be freed soon anyway, we'll just avoid the extra free/alloc and call + * it a wash */ + *method = pubkey; + *method_len = sp1 - pubkey - 1; + + *pubkeydata = tmp; + *pubkeydata_len = tmp_len; + + return 0; +} + +static int +memory_read_privatekey(LIBSSH2_SESSION * session, + const LIBSSH2_HOSTKEY_METHOD ** hostkey_method, + void **hostkey_abstract, + const unsigned char *method, int method_len, + const char *privkeyfiledata, size_t privkeyfiledata_len, + const char *passphrase) +{ + const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = + libssh2_hostkey_methods(); + + *hostkey_method = NULL; + *hostkey_abstract = NULL; + while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) { + if ((*hostkey_methods_avail)->initPEMFromMemory + && strncmp((*hostkey_methods_avail)->name, (const char *) method, + method_len) == 0) { + *hostkey_method = *hostkey_methods_avail; + break; + } + hostkey_methods_avail++; + } + if (!*hostkey_method) { + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No handler for specified private key"); + } + + if ((*hostkey_method)-> + initPEMFromMemory(session, privkeyfiledata, privkeyfiledata_len, + (unsigned char *) passphrase, + hostkey_abstract)) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to initialize private key from file"); + } + + return 0; +} + +/* libssh2_file_read_privatekey + * Read a PEM encoded private key from an id_??? style file + */ +static int +file_read_privatekey(LIBSSH2_SESSION * session, + const LIBSSH2_HOSTKEY_METHOD ** hostkey_method, + void **hostkey_abstract, + const unsigned char *method, int method_len, + const char *privkeyfile, const char *passphrase) +{ + const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = + libssh2_hostkey_methods(); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading private key file: %s", + privkeyfile); + *hostkey_method = NULL; + *hostkey_abstract = NULL; + while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) { + if ((*hostkey_methods_avail)->initPEM + && strncmp((*hostkey_methods_avail)->name, (const char *) method, + method_len) == 0) { + *hostkey_method = *hostkey_methods_avail; + break; + } + hostkey_methods_avail++; + } + if (!*hostkey_method) { + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No handler for specified private key"); + } + + if ((*hostkey_method)-> + initPEM(session, privkeyfile, (unsigned char *) passphrase, + hostkey_abstract)) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to initialize private key from file"); + } + + return 0; +} + +struct privkey_file { + const char *filename; + const char *passphrase; +}; + +static int +sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, + const unsigned char *data, size_t data_len, void **abstract) +{ + struct privkey_file *pk_file = (struct privkey_file *) (*abstract); + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + void *hostkey_abstract; + struct iovec datavec; + int rc; + + rc = memory_read_privatekey(session, &privkeyobj, &hostkey_abstract, + session->userauth_pblc_method, + session->userauth_pblc_method_len, + pk_file->filename, + strlen(pk_file->filename), + pk_file->passphrase); + if(rc) + return rc; + + libssh2_prepare_iovec(&datavec, 1); + datavec.iov_base = (void *)data; + datavec.iov_len = data_len; + + if (privkeyobj->signv(session, sig, sig_len, 1, &datavec, + &hostkey_abstract)) { + if (privkeyobj->dtor) { + privkeyobj->dtor(session, abstract); + } + return -1; + } + + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return 0; +} + +static int +sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, + const unsigned char *data, size_t data_len, void **abstract) +{ + struct privkey_file *privkey_file = (struct privkey_file *) (*abstract); + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + void *hostkey_abstract; + struct iovec datavec; + int rc; + + rc = file_read_privatekey(session, &privkeyobj, &hostkey_abstract, + session->userauth_pblc_method, + session->userauth_pblc_method_len, + privkey_file->filename, + privkey_file->passphrase); + if(rc) + return rc; + + libssh2_prepare_iovec(&datavec, 1); + datavec.iov_base = (void *)data; + datavec.iov_len = data_len; + + if (privkeyobj->signv(session, sig, sig_len, 1, &datavec, + &hostkey_abstract)) { + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return -1; + } + + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return 0; +} + + + +/* userauth_hostbased_fromfile + * Authenticate using a keypair found in the named files + */ +static int +userauth_hostbased_fromfile(LIBSSH2_SESSION *session, + const char *username, size_t username_len, + const char *publickey, const char *privatekey, + const char *passphrase, const char *hostname, + size_t hostname_len, + const char *local_username, + size_t local_username_len) +{ + int rc; + + if (session->userauth_host_state == libssh2_NB_state_idle) { + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + unsigned char *pubkeydata, *sig = NULL; + size_t pubkeydata_len = 0; + size_t sig_len = 0; + void *abstract; + unsigned char buf[5]; + struct iovec datavec[4]; + + /* Zero the whole thing out */ + memset(&session->userauth_host_packet_requirev_state, 0, + sizeof(session->userauth_host_packet_requirev_state)); + + if (publickey) { + rc = file_read_publickey(session, &session->userauth_host_method, + &session->userauth_host_method_len, + &pubkeydata, &pubkeydata_len, publickey); + if(rc) + /* Note: file_read_publickey() calls _libssh2_error() */ + return rc; + } + else { + /* Compute public key from private key. */ + rc = _libssh2_pub_priv_keyfile(session, + &session->userauth_host_method, + &session->userauth_host_method_len, + &pubkeydata, &pubkeydata_len, + privatekey, passphrase); + if (rc) + /* libssh2_pub_priv_keyfile calls _libssh2_error() */ + return rc; + } + + /* + * 52 = packet_type(1) + username_len(4) + servicename_len(4) + + * service_name(14)"ssh-connection" + authmethod_len(4) + + * authmethod(9)"hostbased" + method_len(4) + pubkeydata_len(4) + + * hostname_len(4) + local_username_len(4) + */ + session->userauth_host_packet_len = + username_len + session->userauth_host_method_len + hostname_len + + local_username_len + pubkeydata_len + 52; + + /* + * Preallocate space for an overall length, method name again, + * and the signature, which won't be any larger than the size of + * the publickeydata itself + */ + session->userauth_host_s = session->userauth_host_packet = + LIBSSH2_ALLOC(session, + session->userauth_host_packet_len + 4 + + (4 + session->userauth_host_method_len) + + (4 + pubkeydata_len)); + if (!session->userauth_host_packet) { + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + LIBSSH2_FREE(session, pubkeydata); + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory"); + } + + *(session->userauth_host_s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&session->userauth_host_s, username, username_len); + _libssh2_store_str(&session->userauth_host_s, "ssh-connection", 14); + _libssh2_store_str(&session->userauth_host_s, "hostbased", 9); + _libssh2_store_str(&session->userauth_host_s, + (const char *)session->userauth_host_method, + session->userauth_host_method_len); + _libssh2_store_str(&session->userauth_host_s, (const char *)pubkeydata, + pubkeydata_len); + LIBSSH2_FREE(session, pubkeydata); + _libssh2_store_str(&session->userauth_host_s, hostname, hostname_len); + _libssh2_store_str(&session->userauth_host_s, local_username, + local_username_len); + + rc = file_read_privatekey(session, &privkeyobj, &abstract, + session->userauth_host_method, + session->userauth_host_method_len, + privatekey, passphrase); + if(rc) { + /* Note: file_read_privatekey() calls _libssh2_error() */ + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + return rc; + } + + _libssh2_htonu32(buf, session->session_id_len); + libssh2_prepare_iovec(datavec, 4); + datavec[0].iov_base = (void *)buf; + datavec[0].iov_len = 4; + datavec[1].iov_base = (void *)session->session_id; + datavec[1].iov_len = session->session_id_len; + datavec[2].iov_base = (void *)session->userauth_host_packet; + datavec[2].iov_len = session->userauth_host_packet_len; + + if (privkeyobj && privkeyobj->signv && + privkeyobj->signv(session, &sig, &sig_len, 3, + datavec, &abstract)) { + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } + return -1; + } + + if (privkeyobj && privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } + + if (sig_len > pubkeydata_len) { + unsigned char *newpacket; + /* Should *NEVER* happen, but...well.. better safe than sorry */ + newpacket = LIBSSH2_REALLOC(session, session->userauth_host_packet, + session->userauth_host_packet_len + 4 + + (4 + session->userauth_host_method_len) + + (4 + sig_len)); /* PK sigblob */ + if (!newpacket) { + LIBSSH2_FREE(session, sig); + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating additional space for " + "userauth-hostbased packet"); + } + session->userauth_host_packet = newpacket; + } + + session->userauth_host_s = + session->userauth_host_packet + session->userauth_host_packet_len; + + _libssh2_store_u32(&session->userauth_host_s, + 4 + session->userauth_host_method_len + 4 + sig_len); + _libssh2_store_str(&session->userauth_host_s, + (const char *)session->userauth_host_method, + session->userauth_host_method_len); + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + + _libssh2_store_str(&session->userauth_host_s, (const char *)sig, + sig_len); + LIBSSH2_FREE(session, sig); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting hostbased authentication"); + + session->userauth_host_state = libssh2_NB_state_created; + } + + if (session->userauth_host_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_host_packet, + session->userauth_host_s - + session->userauth_host_packet, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } + else if (rc) { + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + session->userauth_host_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-hostbased request"); + } + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + + session->userauth_host_state = libssh2_NB_state_sent; + } + + if (session->userauth_host_state == libssh2_NB_state_sent) { + static const unsigned char reply_codes[3] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; + size_t data_len; + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_host_data, + &data_len, 0, NULL, 0, + &session-> + userauth_host_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } + + session->userauth_host_state = libssh2_NB_state_idle; + if (rc) { + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Auth failed"); + } + + if (session->userauth_host_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Hostbased authentication successful"); + /* We are us and we've proved it. */ + LIBSSH2_FREE(session, session->userauth_host_data); + session->userauth_host_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + return 0; + } + } + + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, session->userauth_host_data); + session->userauth_host_data = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid signature for supplied public key, or bad " + "username/public key combination"); +} + +/* libssh2_userauth_hostbased_fromfile_ex + * Authenticate using a keypair found in the named files + */ +LIBSSH2_API int +libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, + const char *user, + unsigned int user_len, + const char *publickey, + const char *privatekey, + const char *passphrase, + const char *host, + unsigned int host_len, + const char *localuser, + unsigned int localuser_len) +{ + int rc; + BLOCK_ADJUST(rc, session, + userauth_hostbased_fromfile(session, user, user_len, + publickey, privatekey, + passphrase, host, host_len, + localuser, localuser_len)); + return rc; +} + + + +int +_libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const unsigned char *pubkeydata, + unsigned long pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), + void *abstract) +{ + unsigned char reply_codes[4] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, + SSH_MSG_USERAUTH_PK_OK, 0 + }; + int rc; + unsigned char *s; + + if (session->userauth_pblc_state == libssh2_NB_state_idle) { + + /* + * The call to _libssh2_ntohu32 later relies on pubkeydata having at + * least 4 valid bytes containing the length of the method name. + */ + if (pubkeydata_len < 4) + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid public key, too short"); + + /* Zero the whole thing out */ + memset(&session->userauth_pblc_packet_requirev_state, 0, + sizeof(session->userauth_pblc_packet_requirev_state)); + + /* + * As an optimisation, userauth_publickey_fromfile reuses a + * previously allocated copy of the method name to avoid an extra + * allocation/free. + * For other uses, we allocate and populate it here. + */ + if (!session->userauth_pblc_method) { + session->userauth_pblc_method_len = _libssh2_ntohu32(pubkeydata); + + if(session->userauth_pblc_method_len > pubkeydata_len) + /* the method length simply cannot be longer than the entire + passed in data, so we use this to detect crazy input + data */ + return _libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid public key"); + + session->userauth_pblc_method = + LIBSSH2_ALLOC(session, session->userauth_pblc_method_len); + if (!session->userauth_pblc_method) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for public key " + "data"); + } + memcpy(session->userauth_pblc_method, pubkeydata + 4, + session->userauth_pblc_method_len); + } + /* + * The length of the method name read from plaintext prefix in the + * file must match length embedded in the key. + * TODO: The data should match too but we don't check that. Should we? + */ + else if (session->userauth_pblc_method_len != + _libssh2_ntohu32(pubkeydata)) + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid public key"); + + /* + * 45 = packet_type(1) + username_len(4) + servicename_len(4) + + * service_name(14)"ssh-connection" + authmethod_len(4) + + * authmethod(9)"publickey" + sig_included(1)'\0' + algmethod_len(4) + + * publickey_len(4) + */ + session->userauth_pblc_packet_len = + username_len + session->userauth_pblc_method_len + pubkeydata_len + + 45; + + /* + * Preallocate space for an overall length, method name again, and the + * signature, which won't be any larger than the size of the + * publickeydata itself. + * + * Note that the 'pubkeydata_len' extra bytes allocated here will not + * be used in this first send, but will be used in the later one where + * this same allocation is re-used. + */ + s = session->userauth_pblc_packet = + LIBSSH2_ALLOC(session, + session->userauth_pblc_packet_len + 4 + + (4 + session->userauth_pblc_method_len) + + (4 + pubkeydata_len)); + if (!session->userauth_pblc_packet) { + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory"); + } + + *s++ = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", 14); + _libssh2_store_str(&s, "publickey", 9); + + session->userauth_pblc_b = s; + /* Not sending signature with *this* packet */ + *s++ = 0; + + _libssh2_store_str(&s, (const char *)session->userauth_pblc_method, + session->userauth_pblc_method_len); + _libssh2_store_str(&s, (const char *)pubkeydata, pubkeydata_len); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting publickey authentication"); + + session->userauth_pblc_state = libssh2_NB_state_created; + } + + if (session->userauth_pblc_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_pblc_packet, + session->userauth_pblc_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + else if (rc) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-publickey request"); + } + + session->userauth_pblc_state = libssh2_NB_state_sent; + } + + if (session->userauth_pblc_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_pblc_data, + &session->userauth_pblc_data_len, 0, + NULL, 0, + &session-> + userauth_pblc_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } + else if (rc) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Waiting for USERAUTH response"); + } + + if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Pubkey authentication prematurely successful"); + /* + * God help any SSH server that allows an UNVERIFIED + * public key to validate the user + */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_pblc_state = libssh2_NB_state_idle; + return 0; + } + + if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_FAILURE) { + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Username/PublicKey combination invalid"); + } + + /* Semi-Success! */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + + *session->userauth_pblc_b = 0x01; + session->userauth_pblc_state = libssh2_NB_state_sent1; + } + + if (session->userauth_pblc_state == libssh2_NB_state_sent1) { + unsigned char *buf; + unsigned char *sig; + size_t sig_len; + + s = buf = LIBSSH2_ALLOC(session, 4 + session->session_id_len + + session->userauth_pblc_packet_len); + if (!buf) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "userauth-publickey signed data"); + } + + _libssh2_store_str(&s, (const char *)session->session_id, + session->session_id_len); + + memcpy (s, session->userauth_pblc_packet, + session->userauth_pblc_packet_len); + s += session->userauth_pblc_packet_len; + + rc = sign_callback(session, &sig, &sig_len, buf, s - buf, abstract); + LIBSSH2_FREE(session, buf); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } else if (rc) { + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Callback returned error"); + } + + /* + * If this function was restarted, pubkeydata_len might still be 0 + * which will cause an unnecessary but harmless realloc here. + */ + if (sig_len > pubkeydata_len) { + unsigned char *newpacket; + /* Should *NEVER* happen, but...well.. better safe than sorry */ + newpacket = LIBSSH2_REALLOC(session, + session->userauth_pblc_packet, + session->userauth_pblc_packet_len + 4 + + (4 + session->userauth_pblc_method_len) + + (4 + sig_len)); /* PK sigblob */ + if (!newpacket) { + LIBSSH2_FREE(session, sig); + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating additional space for " + "userauth-publickey packet"); + } + session->userauth_pblc_packet = newpacket; + } + + s = session->userauth_pblc_packet + session->userauth_pblc_packet_len; + session->userauth_pblc_b = NULL; + + _libssh2_store_u32(&s, + 4 + session->userauth_pblc_method_len + 4 + sig_len); + _libssh2_store_str(&s, (const char *)session->userauth_pblc_method, + session->userauth_pblc_method_len); + + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + + _libssh2_store_str(&s, (const char *)sig, sig_len); + LIBSSH2_FREE(session, sig); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting publickey authentication -- phase 2"); + + session->userauth_pblc_s = s; + session->userauth_pblc_state = libssh2_NB_state_sent2; + } + + if (session->userauth_pblc_state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, session->userauth_pblc_packet, + session->userauth_pblc_s - + session->userauth_pblc_packet, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } else if (rc) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-publickey request"); + } + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + + session->userauth_pblc_state = libssh2_NB_state_sent3; + } + + /* PK_OK is no longer valid */ + reply_codes[2] = 0; + + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_pblc_data, + &session->userauth_pblc_data_len, 0, NULL, 0, + &session->userauth_pblc_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list"); + } else if (rc) { + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Waiting for publickey USERAUTH response"); + } + + if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Publickey authentication successful"); + /* We are us and we've proved it. */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_pblc_state = libssh2_NB_state_idle; + return 0; + } + + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid signature for supplied public key, or bad " + "username/public key combination"); +} + + /* + * userauth_publickey_frommemory + * Authenticate using a keypair from memory + */ +static int +userauth_publickey_frommemory(LIBSSH2_SESSION *session, + const char *username, + size_t username_len, + const char *publickeydata, + size_t publickeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + unsigned char *pubkeydata = NULL; + size_t pubkeydata_len = 0; + struct privkey_file privkey_file; + void *abstract = &privkey_file; + int rc; + + privkey_file.filename = privatekeydata; + privkey_file.passphrase = passphrase; + + if (session->userauth_pblc_state == libssh2_NB_state_idle) { + if (publickeydata_len && publickeydata) { + rc = memory_read_publickey(session, &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, + publickeydata, publickeydata_len); + if(rc) + return rc; + } + else if (privatekeydata_len && privatekeydata) { + /* Compute public key from private key. */ + if (_libssh2_pub_priv_keyfilememory(session, + &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, + privatekeydata, privatekeydata_len, + passphrase)) + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key."); + } + else { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid data in public and private key."); + } + } + + rc = _libssh2_userauth_publickey(session, username, username_len, + pubkeydata, pubkeydata_len, + sign_frommemory, &abstract); + if(pubkeydata) + LIBSSH2_FREE(session, pubkeydata); + + return rc; +} + +/* + * userauth_publickey_fromfile + * Authenticate using a keypair found in the named files + */ +static int +userauth_publickey_fromfile(LIBSSH2_SESSION *session, + const char *username, + size_t username_len, + const char *publickey, + const char *privatekey, + const char *passphrase) +{ + unsigned char *pubkeydata = NULL; + size_t pubkeydata_len = 0; + struct privkey_file privkey_file; + void *abstract = &privkey_file; + int rc; + + privkey_file.filename = privatekey; + privkey_file.passphrase = passphrase; + + if (session->userauth_pblc_state == libssh2_NB_state_idle) { + if (publickey) { + rc = file_read_publickey(session, &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len,publickey); + if (rc) + return rc; + } + else { + /* Compute public key from private key. */ + rc = _libssh2_pub_priv_keyfile(session, + &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, + privatekey, passphrase); + + /* _libssh2_pub_priv_keyfile calls _libssh2_error() */ + if (rc) + return rc; + } + } + + rc = _libssh2_userauth_publickey(session, username, username_len, + pubkeydata, pubkeydata_len, + sign_fromfile, &abstract); + if(pubkeydata) + LIBSSH2_FREE(session, pubkeydata); + + return rc; +} + +/* libssh2_userauth_publickey_frommemory + * Authenticate using a keypair from memory + */ +LIBSSH2_API int +libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, + const char *user, + size_t user_len, + const char *publickeyfiledata, + size_t publickeyfiledata_len, + const char *privatekeyfiledata, + size_t privatekeyfiledata_len, + const char *passphrase) +{ + int rc; + + if(NULL == passphrase) + /* if given a NULL pointer, make it point to a zero-length + string to save us from having to check this all over */ + passphrase=""; + + BLOCK_ADJUST(rc, session, + userauth_publickey_frommemory(session, user, user_len, + publickeyfiledata, + publickeyfiledata_len, + privatekeyfiledata, + privatekeyfiledata_len, + passphrase)); + return rc; +} + +/* libssh2_userauth_publickey_fromfile_ex + * Authenticate using a keypair found in the named files + */ +LIBSSH2_API int +libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, + const char *user, + unsigned int user_len, + const char *publickey, + const char *privatekey, + const char *passphrase) +{ + int rc; + + if(NULL == passphrase) + /* if given a NULL pointer, make it point to a zero-length + string to save us from having to check this all over */ + passphrase=""; + + BLOCK_ADJUST(rc, session, + userauth_publickey_fromfile(session, user, user_len, + publickey, privatekey, + passphrase)); + return rc; +} + +/* libssh2_userauth_publickey_ex + * Authenticate using an external callback function + */ +LIBSSH2_API int +libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *user, + const unsigned char *pubkeydata, + size_t pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), + void **abstract) +{ + int rc; + + if(!session) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, session, + _libssh2_userauth_publickey(session, user, strlen(user), + pubkeydata, pubkeydata_len, + sign_callback, abstract)); + return rc; +} + + + +/* + * userauth_keyboard_interactive + * + * Authenticate using a challenge-response authentication + */ +static int +userauth_keyboard_interactive(LIBSSH2_SESSION * session, + const char *username, + unsigned int username_len, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) +{ + unsigned char *s; + int rc; + + static const unsigned char reply_codes[4] = { + SSH_MSG_USERAUTH_SUCCESS, + SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 + }; + unsigned int language_tag_len; + unsigned int i; + + if (session->userauth_kybd_state == libssh2_NB_state_idle) { + session->userauth_kybd_auth_name = NULL; + session->userauth_kybd_auth_instruction = NULL; + session->userauth_kybd_num_prompts = 0; + session->userauth_kybd_auth_failure = 1; + session->userauth_kybd_prompts = NULL; + session->userauth_kybd_responses = NULL; + + /* Zero the whole thing out */ + memset(&session->userauth_kybd_packet_requirev_state, 0, + sizeof(session->userauth_kybd_packet_requirev_state)); + + session->userauth_kybd_packet_len = + 1 /* byte SSH_MSG_USERAUTH_REQUEST */ + + 4 + username_len /* string user name (ISO-10646 UTF-8, as + defined in [RFC-3629]) */ + + 4 + 14 /* string service name (US-ASCII) */ + + 4 + 20 /* string "keyboard-interactive" (US-ASCII) */ + + 4 + 0 /* string language tag (as defined in + [RFC-3066]) */ + + 4 + 0 /* string submethods (ISO-10646 UTF-8) */ + ; + + session->userauth_kybd_data = s = + LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); + if (!s) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive authentication"); + } + + *s++ = SSH_MSG_USERAUTH_REQUEST; + + /* user name */ + _libssh2_store_str(&s, username, username_len); + + /* service name */ + _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1); + + /* "keyboard-interactive" */ + _libssh2_store_str(&s, "keyboard-interactive", + sizeof("keyboard-interactive") - 1); + /* language tag */ + _libssh2_store_u32(&s, 0); + + /* submethods */ + _libssh2_store_u32(&s, 0); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting keyboard-interactive authentication"); + + session->userauth_kybd_state = libssh2_NB_state_created; + } + + if (session->userauth_kybd_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_kybd_data, + session->userauth_kybd_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } else if (rc) { + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + session->userauth_kybd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send keyboard-interactive request"); + } + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + + session->userauth_kybd_state = libssh2_NB_state_sent; + } + + for(;;) { + if (session->userauth_kybd_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_kybd_data, + &session->userauth_kybd_data_len, + 0, NULL, 0, + &session-> + userauth_kybd_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + } else if (rc) { + session->userauth_kybd_state = libssh2_NB_state_idle; + return _libssh2_error(session, + LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Waiting for keyboard USERAUTH response"); + } + + if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Keyboard-interactive authentication successful"); + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_kybd_state = libssh2_NB_state_idle; + return 0; + } + + if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_FAILURE) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Keyboard-interactive authentication failed"); + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + session->userauth_kybd_state = libssh2_NB_state_idle; + return _libssh2_error(session, + LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Authentication failed " + "(keyboard-interactive)"); + } + + /* server requested PAM-like conversation */ + s = session->userauth_kybd_data + 1; + + /* string name (ISO-10646 UTF-8) */ + session->userauth_kybd_auth_name_len = _libssh2_ntohu32(s); + s += 4; + if(session->userauth_kybd_auth_name_len) { + session->userauth_kybd_auth_name = + LIBSSH2_ALLOC(session, + session->userauth_kybd_auth_name_len); + if (!session->userauth_kybd_auth_name) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive 'name' " + "request field"); + goto cleanup; + } + memcpy(session->userauth_kybd_auth_name, s, + session->userauth_kybd_auth_name_len); + s += session->userauth_kybd_auth_name_len; + } + + /* string instruction (ISO-10646 UTF-8) */ + session->userauth_kybd_auth_instruction_len = _libssh2_ntohu32(s); + s += 4; + if(session->userauth_kybd_auth_instruction_len) { + session->userauth_kybd_auth_instruction = + LIBSSH2_ALLOC(session, + session->userauth_kybd_auth_instruction_len); + if (!session->userauth_kybd_auth_instruction) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive 'instruction' " + "request field"); + goto cleanup; + } + memcpy(session->userauth_kybd_auth_instruction, s, + session->userauth_kybd_auth_instruction_len); + s += session->userauth_kybd_auth_instruction_len; + } + + /* string language tag (as defined in [RFC-3066]) */ + language_tag_len = _libssh2_ntohu32(s); + s += 4; + + /* ignoring this field as deprecated */ + s += language_tag_len; + + /* int num-prompts */ + session->userauth_kybd_num_prompts = _libssh2_ntohu32(s); + s += 4; + + if(session->userauth_kybd_num_prompts) { + session->userauth_kybd_prompts = + LIBSSH2_CALLOC(session, + sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * + session->userauth_kybd_num_prompts); + if (!session->userauth_kybd_prompts) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive prompts array"); + goto cleanup; + } + + session->userauth_kybd_responses = + LIBSSH2_CALLOC(session, + sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * + session->userauth_kybd_num_prompts); + if (!session->userauth_kybd_responses) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive responses array"); + goto cleanup; + } + + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + /* string prompt[1] (ISO-10646 UTF-8) */ + session->userauth_kybd_prompts[i].length = + _libssh2_ntohu32(s); + s += 4; + session->userauth_kybd_prompts[i].text = + LIBSSH2_CALLOC(session, + session->userauth_kybd_prompts[i].length); + if (!session->userauth_kybd_prompts[i].text) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive prompt message"); + goto cleanup; + } + memcpy(session->userauth_kybd_prompts[i].text, s, + session->userauth_kybd_prompts[i].length); + s += session->userauth_kybd_prompts[i].length; + + /* boolean echo[1] */ + session->userauth_kybd_prompts[i].echo = *s++; + } + } + + response_callback(session->userauth_kybd_auth_name, + session->userauth_kybd_auth_name_len, + session->userauth_kybd_auth_instruction, + session->userauth_kybd_auth_instruction_len, + session->userauth_kybd_num_prompts, + session->userauth_kybd_prompts, + session->userauth_kybd_responses, + &session->abstract); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Keyboard-interactive response callback function" + " invoked"); + + session->userauth_kybd_packet_len = + 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */ + + 4 /* int num-responses */ + ; + + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + /* string response[1] (ISO-10646 UTF-8) */ + session->userauth_kybd_packet_len += + 4 + session->userauth_kybd_responses[i].length; + } + + /* A new userauth_kybd_data area is to be allocated, free the + former one. */ + LIBSSH2_FREE(session, session->userauth_kybd_data); + + session->userauth_kybd_data = s = + LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); + if (!s) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for keyboard-" + "interactive response packet"); + goto cleanup; + } + + *s = SSH_MSG_USERAUTH_INFO_RESPONSE; + s++; + _libssh2_store_u32(&s, session->userauth_kybd_num_prompts); + + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + _libssh2_store_str(&s, + session->userauth_kybd_responses[i].text, + session->userauth_kybd_responses[i].length); + } + + session->userauth_kybd_state = libssh2_NB_state_sent1; + } + + if (session->userauth_kybd_state == libssh2_NB_state_sent1) { + rc = _libssh2_transport_send(session, session->userauth_kybd_data, + session->userauth_kybd_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-keyboard-interactive" + " request"); + goto cleanup; + } + + session->userauth_kybd_auth_failure = 0; + } + + cleanup: + /* + * It's safe to clean all the data here, because unallocated pointers + * are filled by zeroes + */ + + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + + if (session->userauth_kybd_prompts) { + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + LIBSSH2_FREE(session, session->userauth_kybd_prompts[i].text); + session->userauth_kybd_prompts[i].text = NULL; + } + } + + if (session->userauth_kybd_responses) { + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + LIBSSH2_FREE(session, + session->userauth_kybd_responses[i].text); + session->userauth_kybd_responses[i].text = NULL; + } + } + + if(session->userauth_kybd_prompts) { + LIBSSH2_FREE(session, session->userauth_kybd_prompts); + session->userauth_kybd_prompts = NULL; + } + if(session->userauth_kybd_responses) { + LIBSSH2_FREE(session, session->userauth_kybd_responses); + session->userauth_kybd_responses = NULL; + } + if(session->userauth_kybd_auth_name) { + LIBSSH2_FREE(session, session->userauth_kybd_auth_name); + session->userauth_kybd_auth_name = NULL; + } + if(session->userauth_kybd_auth_instruction) { + LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction); + session->userauth_kybd_auth_instruction = NULL; + } + + if (session->userauth_kybd_auth_failure) { + session->userauth_kybd_state = libssh2_NB_state_idle; + return -1; + } + + session->userauth_kybd_state = libssh2_NB_state_sent; + } +} + +/* + * libssh2_userauth_keyboard_interactive_ex + * + * Authenticate using a challenge-response authentication + */ +LIBSSH2_API int +libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, + const char *user, + unsigned int user_len, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) +{ + int rc; + BLOCK_ADJUST(rc, session, + userauth_keyboard_interactive(session, user, user_len, + response_callback)); + return rc; +} diff --git a/libssh2/src/userauth.h b/libssh2/src/userauth.h new file mode 100644 index 000000000..c0442ae15 --- /dev/null +++ b/libssh2/src/userauth.h @@ -0,0 +1,50 @@ +#ifndef LIBSSH2_USERAUTH_H +#define LIBSSH2_USERAUTH_H +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2009-2010 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +int +_libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const unsigned char *pubkeydata, + unsigned long pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), + void *abstract); + +#endif /* LIBSSH2_USERAUTH_H */ diff --git a/libssh2/src/version.c b/libssh2/src/version.c new file mode 100644 index 000000000..408f83a39 --- /dev/null +++ b/libssh2/src/version.c @@ -0,0 +1,54 @@ +/* Copyright (C) 2009 Daniel Stenberg. All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" + +/* + libssh2_version() can be used like this: + + if (!libssh2_version(LIBSSH2_VERSION_NUM)) { + fprintf (stderr, "Runtime libssh2 version too old!\n"); + exit(1); + } +*/ +LIBSSH2_API +const char *libssh2_version(int req_version_num) +{ + if(req_version_num <= LIBSSH2_VERSION_NUM) + return LIBSSH2_VERSION; + return NULL; /* this is not a suitable library! */ +} diff --git a/libssh2/src/wincng.c b/libssh2/src/wincng.c new file mode 100644 index 000000000..d3271b3e3 --- /dev/null +++ b/libssh2/src/wincng.c @@ -0,0 +1,2076 @@ +/* + * Copyright (C) 2013-2015 Marc Hoersken + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_WINCNG /* compile only if we build with wincng */ + +/* required for cross-compilation against the w64 mingw-runtime package */ +#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) +#undef _WIN32_WINNT +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 +#endif + +/* specify the required libraries for dependencies using MSVC */ +#ifdef _MSC_VER +#pragma comment(lib, "bcrypt.lib") +#ifdef HAVE_LIBCRYPT32 +#pragma comment(lib, "crypt32.lib") +#endif +#endif + +#include +#include +#include + +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_LIBCRYPT32 +#include +#endif + +#define PEM_RSA_HEADER "-----BEGIN RSA PRIVATE KEY-----" +#define PEM_RSA_FOOTER "-----END RSA PRIVATE KEY-----" +#define PEM_DSA_HEADER "-----BEGIN DSA PRIVATE KEY-----" +#define PEM_DSA_FOOTER "-----END DSA PRIVATE KEY-----" + + +/*******************************************************************/ +/* + * Windows CNG backend: Missing definitions (for MinGW[-w64]) + */ +#ifndef BCRYPT_SUCCESS +#define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + +#ifndef BCRYPT_RNG_ALGORITHM +#define BCRYPT_RNG_ALGORITHM L"RNG" +#endif + +#ifndef BCRYPT_MD5_ALGORITHM +#define BCRYPT_MD5_ALGORITHM L"MD5" +#endif + +#ifndef BCRYPT_SHA1_ALGORITHM +#define BCRYPT_SHA1_ALGORITHM L"SHA1" +#endif + +#ifndef BCRYPT_SHA256_ALGORITHM +#define BCRYPT_SHA256_ALGORITHM L"SHA256" +#endif + +#ifndef BCRYPT_SHA512_ALGORITHM +#define BCRYPT_SHA512_ALGORITHM L"SHA512" +#endif + +#ifndef BCRYPT_RSA_ALGORITHM +#define BCRYPT_RSA_ALGORITHM L"RSA" +#endif + +#ifndef BCRYPT_DSA_ALGORITHM +#define BCRYPT_DSA_ALGORITHM L"DSA" +#endif + +#ifndef BCRYPT_AES_ALGORITHM +#define BCRYPT_AES_ALGORITHM L"AES" +#endif + +#ifndef BCRYPT_RC4_ALGORITHM +#define BCRYPT_RC4_ALGORITHM L"RC4" +#endif + +#ifndef BCRYPT_3DES_ALGORITHM +#define BCRYPT_3DES_ALGORITHM L"3DES" +#endif + +#ifndef BCRYPT_ALG_HANDLE_HMAC_FLAG +#define BCRYPT_ALG_HANDLE_HMAC_FLAG 0x00000008 +#endif + +#ifndef BCRYPT_DSA_PUBLIC_BLOB +#define BCRYPT_DSA_PUBLIC_BLOB L"DSAPUBLICBLOB" +#endif + +#ifndef BCRYPT_DSA_PUBLIC_MAGIC +#define BCRYPT_DSA_PUBLIC_MAGIC 0x42505344 /* DSPB */ +#endif + +#ifndef BCRYPT_DSA_PRIVATE_BLOB +#define BCRYPT_DSA_PRIVATE_BLOB L"DSAPRIVATEBLOB" +#endif + +#ifndef BCRYPT_DSA_PRIVATE_MAGIC +#define BCRYPT_DSA_PRIVATE_MAGIC 0x56505344 /* DSPV */ +#endif + +#ifndef BCRYPT_RSAPUBLIC_BLOB +#define BCRYPT_RSAPUBLIC_BLOB L"RSAPUBLICBLOB" +#endif + +#ifndef BCRYPT_RSAPUBLIC_MAGIC +#define BCRYPT_RSAPUBLIC_MAGIC 0x31415352 /* RSA1 */ +#endif + +#ifndef BCRYPT_RSAFULLPRIVATE_BLOB +#define BCRYPT_RSAFULLPRIVATE_BLOB L"RSAFULLPRIVATEBLOB" +#endif + +#ifndef BCRYPT_RSAFULLPRIVATE_MAGIC +#define BCRYPT_RSAFULLPRIVATE_MAGIC 0x33415352 /* RSA3 */ +#endif + +#ifndef BCRYPT_KEY_DATA_BLOB +#define BCRYPT_KEY_DATA_BLOB L"KeyDataBlob" +#endif + +#ifndef BCRYPT_MESSAGE_BLOCK_LENGTH +#define BCRYPT_MESSAGE_BLOCK_LENGTH L"MessageBlockLength" +#endif + +#ifndef BCRYPT_NO_KEY_VALIDATION +#define BCRYPT_NO_KEY_VALIDATION 0x00000008 +#endif + +#ifndef BCRYPT_BLOCK_PADDING +#define BCRYPT_BLOCK_PADDING 0x00000001 +#endif + +#ifndef BCRYPT_PAD_NONE +#define BCRYPT_PAD_NONE 0x00000001 +#endif + +#ifndef BCRYPT_PAD_PKCS1 +#define BCRYPT_PAD_PKCS1 0x00000002 +#endif + +#ifndef BCRYPT_PAD_OAEP +#define BCRYPT_PAD_OAEP 0x00000004 +#endif + +#ifndef BCRYPT_PAD_PSS +#define BCRYPT_PAD_PSS 0x00000008 +#endif + +#ifndef CRYPT_STRING_ANY +#define CRYPT_STRING_ANY 0x00000007 +#endif + +#ifndef LEGACY_RSAPRIVATE_BLOB +#define LEGACY_RSAPRIVATE_BLOB L"CAPIPRIVATEBLOB" +#endif + +#ifndef PKCS_RSA_PRIVATE_KEY +#define PKCS_RSA_PRIVATE_KEY (LPCSTR)43 +#endif + + +/*******************************************************************/ +/* + * Windows CNG backend: Generic functions + */ + +void +_libssh2_wincng_init(void) +{ + int ret; + + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRNG, + BCRYPT_RNG_ALGORITHM, NULL, 0); + + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashMD5, + BCRYPT_MD5_ALGORITHM, NULL, 0); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA1, + BCRYPT_SHA1_ALGORITHM, NULL, 0); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA256, + BCRYPT_SHA256_ALGORITHM, NULL, 0); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA512, + BCRYPT_SHA512_ALGORITHM, NULL, 0); + + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacMD5, + BCRYPT_MD5_ALGORITHM, NULL, + BCRYPT_ALG_HANDLE_HMAC_FLAG); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA1, + BCRYPT_SHA1_ALGORITHM, NULL, + BCRYPT_ALG_HANDLE_HMAC_FLAG); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA256, + BCRYPT_SHA256_ALGORITHM, NULL, + BCRYPT_ALG_HANDLE_HMAC_FLAG); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA512, + BCRYPT_SHA512_ALGORITHM, NULL, + BCRYPT_ALG_HANDLE_HMAC_FLAG); + + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRSA, + BCRYPT_RSA_ALGORITHM, NULL, 0); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDSA, + BCRYPT_DSA_ALGORITHM, NULL, 0); + + ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC, + BCRYPT_AES_ALGORITHM, NULL, 0); + if (BCRYPT_SUCCESS(ret)) { + ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_CBC, BCRYPT_CHAINING_MODE, + (PBYTE)BCRYPT_CHAIN_MODE_CBC, + sizeof(BCRYPT_CHAIN_MODE_CBC), 0); + if (!BCRYPT_SUCCESS(ret)) { + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); + } + } + + ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA, + BCRYPT_RC4_ALGORITHM, NULL, 0); + if (BCRYPT_SUCCESS(ret)) { + ret = BCryptSetProperty(_libssh2_wincng.hAlgRC4_NA, BCRYPT_CHAINING_MODE, + (PBYTE)BCRYPT_CHAIN_MODE_NA, + sizeof(BCRYPT_CHAIN_MODE_NA), 0); + if (!BCRYPT_SUCCESS(ret)) { + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); + } + } + + ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlg3DES_CBC, + BCRYPT_3DES_ALGORITHM, NULL, 0); + if (BCRYPT_SUCCESS(ret)) { + ret = BCryptSetProperty(_libssh2_wincng.hAlg3DES_CBC, BCRYPT_CHAINING_MODE, + (PBYTE)BCRYPT_CHAIN_MODE_CBC, + sizeof(BCRYPT_CHAIN_MODE_CBC), 0); + if (!BCRYPT_SUCCESS(ret)) { + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); + } + } +} + +void +_libssh2_wincng_free(void) +{ + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRNG, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashMD5, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA1, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA256, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA512, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacMD5, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA1, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA256, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA512, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRSA, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgDSA, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); + + memset(&_libssh2_wincng, 0, sizeof(_libssh2_wincng)); +} + +int +_libssh2_wincng_random(void *buf, int len) +{ + int ret; + + ret = BCryptGenRandom(_libssh2_wincng.hAlgRNG, buf, len, 0); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +static void +_libssh2_wincng_safe_free(void *buf, int len) +{ +#ifndef LIBSSH2_CLEAR_MEMORY + (void)len; +#endif + + if (!buf) + return; + +#ifdef LIBSSH2_CLEAR_MEMORY + if (len > 0) + SecureZeroMemory(buf, len); +#endif + + free(buf); +} + + +/*******************************************************************/ +/* + * Windows CNG backend: Hash functions + */ + +int +_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, + BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen, + unsigned char *key, unsigned long keylen) +{ + BCRYPT_HASH_HANDLE hHash; + unsigned char *pbHashObject; + unsigned long dwHashObject, dwHash, cbData; + int ret; + + ret = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, + (unsigned char *)&dwHash, + sizeof(dwHash), + &cbData, 0); + if ((!BCRYPT_SUCCESS(ret)) || dwHash != hashlen) { + return -1; + } + + ret = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, + (unsigned char *)&dwHashObject, + sizeof(dwHashObject), + &cbData, 0); + if (!BCRYPT_SUCCESS(ret)) { + return -1; + } + + pbHashObject = malloc(dwHashObject); + if (!pbHashObject) { + return -1; + } + + + ret = BCryptCreateHash(hAlg, &hHash, + pbHashObject, dwHashObject, + key, keylen, 0); + if (!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(pbHashObject, dwHashObject); + return -1; + } + + + ctx->hHash = hHash; + ctx->pbHashObject = pbHashObject; + ctx->dwHashObject = dwHashObject; + ctx->cbHash = dwHash; + + return 0; +} + +int +_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, + const unsigned char *data, unsigned long datalen) +{ + int ret; + + ret = BCryptHashData(ctx->hHash, (unsigned char *)data, datalen, 0); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +int +_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx, + unsigned char *hash) +{ + int ret; + + ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0); + + BCryptDestroyHash(ctx->hHash); + ctx->hHash = NULL; + + _libssh2_wincng_safe_free(ctx->pbHashObject, ctx->dwHashObject); + ctx->pbHashObject = NULL; + ctx->dwHashObject = 0; + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +int +_libssh2_wincng_hash(unsigned char *data, unsigned long datalen, + BCRYPT_ALG_HANDLE hAlg, + unsigned char *hash, unsigned long hashlen) +{ + _libssh2_wincng_hash_ctx ctx; + int ret; + + ret = _libssh2_wincng_hash_init(&ctx, hAlg, hashlen, NULL, 0); + if (!ret) { + ret = _libssh2_wincng_hash_update(&ctx, data, datalen); + ret |= _libssh2_wincng_hash_final(&ctx, hash); + } + + return ret; +} + + +/*******************************************************************/ +/* + * Windows CNG backend: HMAC functions + */ + +int +_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx, + unsigned char *hash) +{ + int ret; + + ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +void +_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx) +{ + BCryptDestroyHash(ctx->hHash); + ctx->hHash = NULL; + + _libssh2_wincng_safe_free(ctx->pbHashObject, ctx->dwHashObject); + ctx->pbHashObject = NULL; + ctx->dwHashObject = 0; +} + + +/*******************************************************************/ +/* + * Windows CNG backend: Key functions + */ + +int +_libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len, + unsigned long flags) +{ + BCRYPT_PKCS1_PADDING_INFO paddingInfoPKCS1; + void *pPaddingInfo; + unsigned char *data, *hash; + unsigned long datalen, hashlen; + int ret; + + datalen = m_len; + data = malloc(datalen); + if (!data) { + return -1; + } + + hashlen = SHA_DIGEST_LENGTH; + hash = malloc(hashlen); + if (!hash) { + free(data); + return -1; + } + + memcpy(data, m, datalen); + + ret = _libssh2_wincng_hash(data, datalen, + _libssh2_wincng.hAlgHashSHA1, + hash, hashlen); + + _libssh2_wincng_safe_free(data, datalen); + + if (ret) { + _libssh2_wincng_safe_free(hash, hashlen); + return -1; + } + + datalen = sig_len; + data = malloc(datalen); + if (!data) { + _libssh2_wincng_safe_free(hash, hashlen); + return -1; + } + + if (flags & BCRYPT_PAD_PKCS1) { + paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM; + pPaddingInfo = &paddingInfoPKCS1; + } else + pPaddingInfo = NULL; + + memcpy(data, sig, datalen); + + ret = BCryptVerifySignature(ctx->hKey, pPaddingInfo, + hash, hashlen, data, datalen, flags); + + _libssh2_wincng_safe_free(hash, hashlen); + _libssh2_wincng_safe_free(data, datalen); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +#ifdef HAVE_LIBCRYPT32 +static int +_libssh2_wincng_load_pem(LIBSSH2_SESSION *session, + const char *filename, + const char *passphrase, + const char *headerbegin, + const char *headerend, + unsigned char **data, + unsigned int *datalen) +{ + FILE *fp; + int ret; + + (void)passphrase; + + fp = fopen(filename, "r"); + if (!fp) { + return -1; + } + + ret = _libssh2_pem_parse(session, headerbegin, headerend, + fp, data, datalen); + + fclose(fp); + + return ret; +} + +static int +_libssh2_wincng_load_private(LIBSSH2_SESSION *session, + const char *filename, + const char *passphrase, + unsigned char **ppbEncoded, + unsigned long *pcbEncoded, + int tryLoadRSA, int tryLoadDSA) +{ + unsigned char *data = NULL; + unsigned int datalen = 0; + int ret = -1; + + if (ret && tryLoadRSA) { + ret = _libssh2_wincng_load_pem(session, filename, passphrase, + PEM_RSA_HEADER, PEM_RSA_FOOTER, + &data, &datalen); + } + + if (ret && tryLoadDSA) { + ret = _libssh2_wincng_load_pem(session, filename, passphrase, + PEM_DSA_HEADER, PEM_DSA_FOOTER, + &data, &datalen); + } + + if (!ret) { + *ppbEncoded = data; + *pcbEncoded = datalen; + } + + return ret; +} + +static int +_libssh2_wincng_load_private_memory(LIBSSH2_SESSION *session, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase, + unsigned char **ppbEncoded, + unsigned long *pcbEncoded, + int tryLoadRSA, int tryLoadDSA) +{ + unsigned char *data = NULL; + unsigned int datalen = 0; + int ret = -1; + + (void)passphrase; + + if (ret && tryLoadRSA) { + ret = _libssh2_pem_parse_memory(session, + PEM_RSA_HEADER, PEM_RSA_FOOTER, + privatekeydata, privatekeydata_len, + &data, &datalen); + } + + if (ret && tryLoadDSA) { + ret = _libssh2_pem_parse_memory(session, + PEM_DSA_HEADER, PEM_DSA_FOOTER, + privatekeydata, privatekeydata_len, + &data, &datalen); + } + + if (!ret) { + *ppbEncoded = data; + *pcbEncoded = datalen; + } + + return ret; +} + +static int +_libssh2_wincng_asn_decode(unsigned char *pbEncoded, + unsigned long cbEncoded, + LPCSTR lpszStructType, + unsigned char **ppbDecoded, + unsigned long *pcbDecoded) +{ + unsigned char *pbDecoded = NULL; + unsigned long cbDecoded = 0; + int ret; + + ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + lpszStructType, + pbEncoded, cbEncoded, 0, NULL, + NULL, &cbDecoded); + if (!ret) { + return -1; + } + + pbDecoded = malloc(cbDecoded); + if (!pbDecoded) { + return -1; + } + + ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + lpszStructType, + pbEncoded, cbEncoded, 0, NULL, + pbDecoded, &cbDecoded); + if (!ret) { + _libssh2_wincng_safe_free(pbDecoded, cbDecoded); + return -1; + } + + + *ppbDecoded = pbDecoded; + *pcbDecoded = cbDecoded; + + return 0; +} + +static int +_libssh2_wincng_bn_ltob(unsigned char *pbInput, + unsigned long cbInput, + unsigned char **ppbOutput, + unsigned long *pcbOutput) +{ + unsigned char *pbOutput; + unsigned long cbOutput, index, offset, length; + + if (cbInput < 1) { + return 0; + } + + offset = 0; + length = cbInput - 1; + cbOutput = cbInput; + if (pbInput[length] & (1 << 7)) { + offset++; + cbOutput += offset; + } + + pbOutput = (unsigned char *)malloc(cbOutput); + if (!pbOutput) { + return -1; + } + + pbOutput[0] = 0; + for (index = 0; ((index + offset) < cbOutput) + && (index < cbInput); index++) { + pbOutput[index + offset] = pbInput[length - index]; + } + + + *ppbOutput = pbOutput; + *pcbOutput = cbOutput; + + return 0; +} + +static int +_libssh2_wincng_asn_decode_bn(unsigned char *pbEncoded, + unsigned long cbEncoded, + unsigned char **ppbDecoded, + unsigned long *pcbDecoded) +{ + unsigned char *pbDecoded = NULL, *pbInteger; + unsigned long cbDecoded = 0, cbInteger; + int ret; + + ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, + X509_MULTI_BYTE_UINT, + &pbInteger, &cbInteger); + if (!ret) { + ret = _libssh2_wincng_bn_ltob(((PCRYPT_DATA_BLOB)pbInteger)->pbData, + ((PCRYPT_DATA_BLOB)pbInteger)->cbData, + &pbDecoded, &cbDecoded); + if (!ret) { + *ppbDecoded = pbDecoded; + *pcbDecoded = cbDecoded; + } + _libssh2_wincng_safe_free(pbInteger, cbInteger); + } + + return ret; +} + +static int +_libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded, + unsigned long cbEncoded, + unsigned char ***prpbDecoded, + unsigned long **prcbDecoded, + unsigned long *pcbCount) +{ + PCRYPT_DER_BLOB pBlob; + unsigned char *pbDecoded, **rpbDecoded; + unsigned long cbDecoded, *rcbDecoded, index, length; + int ret; + + ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, + X509_SEQUENCE_OF_ANY, + &pbDecoded, &cbDecoded); + if (!ret) { + length = ((PCRYPT_DATA_BLOB)pbDecoded)->cbData; + + rpbDecoded = malloc(sizeof(PBYTE) * length); + if (rpbDecoded) { + rcbDecoded = malloc(sizeof(DWORD) * length); + if (rcbDecoded) { + for (index = 0; index < length; index++) { + pBlob = &((PCRYPT_DER_BLOB) + ((PCRYPT_DATA_BLOB)pbDecoded)->pbData)[index]; + ret = _libssh2_wincng_asn_decode_bn(pBlob->pbData, + pBlob->cbData, + &rpbDecoded[index], + &rcbDecoded[index]); + if (ret) + break; + } + + if (!ret) { + *prpbDecoded = rpbDecoded; + *prcbDecoded = rcbDecoded; + *pcbCount = length; + } else { + for (length = 0; length < index; length++) { + _libssh2_wincng_safe_free(rpbDecoded[length], + rcbDecoded[length]); + rpbDecoded[length] = NULL; + rcbDecoded[length] = 0; + } + free(rpbDecoded); + free(rcbDecoded); + } + } else { + free(rpbDecoded); + ret = -1; + } + } else { + ret = -1; + } + + _libssh2_wincng_safe_free(pbDecoded, cbDecoded); + } + + return ret; +} +#endif /* HAVE_LIBCRYPT32 */ + +static unsigned long +_libssh2_wincng_bn_size(const unsigned char *bignum, + unsigned long length) +{ + unsigned long offset; + + if (!bignum) + return 0; + + length--; + + offset = 0; + while (!(*(bignum + offset)) && (offset < length)) + offset++; + + length++; + + return length - offset; +} + + +/*******************************************************************/ +/* + * Windows CNG backend: RSA functions + */ + +int +_libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen) +{ + BCRYPT_KEY_HANDLE hKey; + BCRYPT_RSAKEY_BLOB *rsakey; + LPCWSTR lpszBlobType; + unsigned char *key; + unsigned long keylen, offset, mlen, p1len = 0, p2len = 0; + int ret; + + mlen = max(_libssh2_wincng_bn_size(ndata, nlen), + _libssh2_wincng_bn_size(ddata, dlen)); + offset = sizeof(BCRYPT_RSAKEY_BLOB); + keylen = offset + elen + mlen; + if (ddata && dlen > 0) { + p1len = max(_libssh2_wincng_bn_size(pdata, plen), + _libssh2_wincng_bn_size(e1data, e1len)); + p2len = max(_libssh2_wincng_bn_size(qdata, qlen), + _libssh2_wincng_bn_size(e2data, e2len)); + keylen += p1len * 3 + p2len * 2 + mlen; + } + + key = malloc(keylen); + if (!key) { + return -1; + } + + memset(key, 0, keylen); + + + /* https://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ + rsakey = (BCRYPT_RSAKEY_BLOB *)key; + rsakey->BitLength = mlen * 8; + rsakey->cbPublicExp = elen; + rsakey->cbModulus = mlen; + + memcpy(key + offset, edata, elen); + offset += elen; + + if (nlen < mlen) + memcpy(key + offset + mlen - nlen, ndata, nlen); + else + memcpy(key + offset, ndata + nlen - mlen, mlen); + + if (ddata && dlen > 0) { + offset += mlen; + + if (plen < p1len) + memcpy(key + offset + p1len - plen, pdata, plen); + else + memcpy(key + offset, pdata + plen - p1len, p1len); + offset += p1len; + + if (qlen < p2len) + memcpy(key + offset + p2len - qlen, qdata, qlen); + else + memcpy(key + offset, qdata + qlen - p2len, p2len); + offset += p2len; + + if (e1len < p1len) + memcpy(key + offset + p1len - e1len, e1data, e1len); + else + memcpy(key + offset, e1data + e1len - p1len, p1len); + offset += p1len; + + if (e2len < p2len) + memcpy(key + offset + p2len - e2len, e2data, e2len); + else + memcpy(key + offset, e2data + e2len - p2len, p2len); + offset += p2len; + + if (coefflen < p1len) + memcpy(key + offset + p1len - coefflen, coeffdata, coefflen); + else + memcpy(key + offset, coeffdata + coefflen - p1len, p1len); + offset += p1len; + + if (dlen < mlen) + memcpy(key + offset + mlen - dlen, ddata, dlen); + else + memcpy(key + offset, ddata + dlen - mlen, mlen); + + lpszBlobType = BCRYPT_RSAFULLPRIVATE_BLOB; + rsakey->Magic = BCRYPT_RSAFULLPRIVATE_MAGIC; + rsakey->cbPrime1 = p1len; + rsakey->cbPrime2 = p2len; + } else { + lpszBlobType = BCRYPT_RSAPUBLIC_BLOB; + rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; + rsakey->cbPrime1 = 0; + rsakey->cbPrime2 = 0; + } + + + ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, lpszBlobType, + &hKey, key, keylen, 0); + if (!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(key, keylen); + return -1; + } + + + *rsa = malloc(sizeof(libssh2_rsa_ctx)); + if (!(*rsa)) { + BCryptDestroyKey(hKey); + _libssh2_wincng_safe_free(key, keylen); + return -1; + } + + (*rsa)->hKey = hKey; + (*rsa)->pbKeyObject = key; + (*rsa)->cbKeyObject = keylen; + + return 0; +} + +#ifdef HAVE_LIBCRYPT32 +static int +_libssh2_wincng_rsa_new_private_parse(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + unsigned char *pbEncoded, + unsigned long cbEncoded) +{ + BCRYPT_KEY_HANDLE hKey; + unsigned char *pbStructInfo; + unsigned long cbStructInfo; + int ret; + + (void)session; + + ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, + PKCS_RSA_PRIVATE_KEY, + &pbStructInfo, &cbStructInfo); + + _libssh2_wincng_safe_free(pbEncoded, cbEncoded); + + if (ret) { + return -1; + } + + + ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, + LEGACY_RSAPRIVATE_BLOB, &hKey, + pbStructInfo, cbStructInfo, 0); + if (!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(pbStructInfo, cbStructInfo); + return -1; + } + + + *rsa = malloc(sizeof(libssh2_rsa_ctx)); + if (!(*rsa)) { + BCryptDestroyKey(hKey); + _libssh2_wincng_safe_free(pbStructInfo, cbStructInfo); + return -1; + } + + (*rsa)->hKey = hKey; + (*rsa)->pbKeyObject = pbStructInfo; + (*rsa)->cbKeyObject = cbStructInfo; + + return 0; +} +#endif /* HAVE_LIBCRYPT32 */ + +int +_libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + (void)session; + + ret = _libssh2_wincng_load_private(session, filename, + (const char *)passphrase, + &pbEncoded, &cbEncoded, 1, 0); + if (ret) { + return -1; + } + + return _libssh2_wincng_rsa_new_private_parse(rsa, session, + pbEncoded, cbEncoded); +#else + (void)rsa; + (void)filename; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to load RSA key from private key file: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + (void)session; + + ret = _libssh2_wincng_load_private_memory(session, filedata, filedata_len, + (const char *)passphrase, + &pbEncoded, &cbEncoded, 1, 0); + if (ret) { + return -1; + } + + return _libssh2_wincng_rsa_new_private_parse(rsa, session, + pbEncoded, cbEncoded); +#else + (void)rsa; + (void)filedata; + (void)filedata_len; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len) +{ + return _libssh2_wincng_key_sha1_verify(rsa, sig, sig_len, m, m_len, + BCRYPT_PAD_PKCS1); +} + +int +_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len) +{ + BCRYPT_PKCS1_PADDING_INFO paddingInfo; + unsigned char *data, *sig; + unsigned long cbData, datalen, siglen; + int ret; + + datalen = (unsigned long)hash_len; + data = malloc(datalen); + if (!data) { + return -1; + } + + paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM; + + memcpy(data, hash, datalen); + + ret = BCryptSignHash(rsa->hKey, &paddingInfo, + data, datalen, NULL, 0, + &cbData, BCRYPT_PAD_PKCS1); + if (BCRYPT_SUCCESS(ret)) { + siglen = cbData; + sig = LIBSSH2_ALLOC(session, siglen); + if (sig) { + ret = BCryptSignHash(rsa->hKey, &paddingInfo, + data, datalen, sig, siglen, + &cbData, BCRYPT_PAD_PKCS1); + if (BCRYPT_SUCCESS(ret)) { + *signature_len = siglen; + *signature = sig; + } else { + LIBSSH2_FREE(session, sig); + } + } else + ret = STATUS_NO_MEMORY; + } + + _libssh2_wincng_safe_free(data, datalen); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +void +_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa) +{ + if (!rsa) + return; + + BCryptDestroyKey(rsa->hKey); + rsa->hKey = NULL; + + _libssh2_wincng_safe_free(rsa->pbKeyObject, rsa->cbKeyObject); + _libssh2_wincng_safe_free(rsa, sizeof(libssh2_rsa_ctx)); +} + + +/*******************************************************************/ +/* + * Windows CNG backend: DSA functions + */ + +#if LIBSSH2_DSA +int +_libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *gdata, + unsigned long glen, + const unsigned char *ydata, + unsigned long ylen, + const unsigned char *xdata, + unsigned long xlen) +{ + BCRYPT_KEY_HANDLE hKey; + BCRYPT_DSA_KEY_BLOB *dsakey; + LPCWSTR lpszBlobType; + unsigned char *key; + unsigned long keylen, offset, length; + int ret; + + length = max(max(_libssh2_wincng_bn_size(pdata, plen), + _libssh2_wincng_bn_size(gdata, glen)), + _libssh2_wincng_bn_size(ydata, ylen)); + offset = sizeof(BCRYPT_DSA_KEY_BLOB); + keylen = offset + length * 3; + if (xdata && xlen > 0) + keylen += 20; + + key = malloc(keylen); + if (!key) { + return -1; + } + + memset(key, 0, keylen); + + + /* https://msdn.microsoft.com/library/windows/desktop/aa833126.aspx */ + dsakey = (BCRYPT_DSA_KEY_BLOB *)key; + dsakey->cbKey = length; + + memset(dsakey->Count, -1, sizeof(dsakey->Count)); + memset(dsakey->Seed, -1, sizeof(dsakey->Seed)); + + if (qlen < 20) + memcpy(dsakey->q + 20 - qlen, qdata, qlen); + else + memcpy(dsakey->q, qdata + qlen - 20, 20); + + if (plen < length) + memcpy(key + offset + length - plen, pdata, plen); + else + memcpy(key + offset, pdata + plen - length, length); + offset += length; + + if (glen < length) + memcpy(key + offset + length - glen, gdata, glen); + else + memcpy(key + offset, gdata + glen - length, length); + offset += length; + + if (ylen < length) + memcpy(key + offset + length - ylen, ydata, ylen); + else + memcpy(key + offset, ydata + ylen - length, length); + + if (xdata && xlen > 0) { + offset += length; + + if (xlen < 20) + memcpy(key + offset + 20 - xlen, xdata, xlen); + else + memcpy(key + offset, xdata + xlen - 20, 20); + + lpszBlobType = BCRYPT_DSA_PRIVATE_BLOB; + dsakey->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC; + } else { + lpszBlobType = BCRYPT_DSA_PUBLIC_BLOB; + dsakey->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC; + } + + + ret = BCryptImportKeyPair(_libssh2_wincng.hAlgDSA, NULL, lpszBlobType, + &hKey, key, keylen, 0); + if (!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(key, keylen); + return -1; + } + + + *dsa = malloc(sizeof(libssh2_dsa_ctx)); + if (!(*dsa)) { + BCryptDestroyKey(hKey); + _libssh2_wincng_safe_free(key, keylen); + return -1; + } + + (*dsa)->hKey = hKey; + (*dsa)->pbKeyObject = key; + (*dsa)->cbKeyObject = keylen; + + return 0; +} + +#ifdef HAVE_LIBCRYPT32 +static int +_libssh2_wincng_dsa_new_private_parse(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + unsigned char *pbEncoded, + unsigned long cbEncoded) +{ + unsigned char **rpbDecoded; + unsigned long *rcbDecoded, index, length; + int ret; + + (void)session; + + ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded, + &rpbDecoded, &rcbDecoded, &length); + + _libssh2_wincng_safe_free(pbEncoded, cbEncoded); + + if (ret) { + return -1; + } + + + if (length == 6) { + ret = _libssh2_wincng_dsa_new(dsa, + rpbDecoded[1], rcbDecoded[1], + rpbDecoded[2], rcbDecoded[2], + rpbDecoded[3], rcbDecoded[3], + rpbDecoded[4], rcbDecoded[4], + rpbDecoded[5], rcbDecoded[5]); + } else { + ret = -1; + } + + for (index = 0; index < length; index++) { + _libssh2_wincng_safe_free(rpbDecoded[index], rcbDecoded[index]); + rpbDecoded[index] = NULL; + rcbDecoded[index] = 0; + } + + free(rpbDecoded); + free(rcbDecoded); + + return ret; +} +#endif /* HAVE_LIBCRYPT32 */ + +int +_libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + ret = _libssh2_wincng_load_private(session, filename, + (const char *)passphrase, + &pbEncoded, &cbEncoded, 0, 1); + if (ret) { + return -1; + } + + return _libssh2_wincng_dsa_new_private_parse(dsa, session, + pbEncoded, cbEncoded); +#else + (void)dsa; + (void)filename; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to load DSA key from private key file: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + ret = _libssh2_wincng_load_private_memory(session, filedata, filedata_len, + (const char *)passphrase, + &pbEncoded, &cbEncoded, 0, 1); + if (ret) { + return -1; + } + + return _libssh2_wincng_dsa_new_private_parse(dsa, session, + pbEncoded, cbEncoded); +#else + (void)dsa; + (void)filedata; + (void)filedata_len; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa, + const unsigned char *sig_fixed, + const unsigned char *m, + unsigned long m_len) +{ + return _libssh2_wincng_key_sha1_verify(dsa, sig_fixed, 40, m, m_len, 0); +} + +int +_libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa, + const unsigned char *hash, + unsigned long hash_len, + unsigned char *sig_fixed) +{ + unsigned char *data, *sig; + unsigned long cbData, datalen, siglen; + int ret; + + datalen = hash_len; + data = malloc(datalen); + if (!data) { + return -1; + } + + memcpy(data, hash, datalen); + + ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, + NULL, 0, &cbData, 0); + if (BCRYPT_SUCCESS(ret)) { + siglen = cbData; + if (siglen == 40) { + sig = malloc(siglen); + if (sig) { + ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, + sig, siglen, &cbData, 0); + if (BCRYPT_SUCCESS(ret)) { + memcpy(sig_fixed, sig, siglen); + } + + _libssh2_wincng_safe_free(sig, siglen); + } else + ret = STATUS_NO_MEMORY; + } else + ret = STATUS_NO_MEMORY; + } + + _libssh2_wincng_safe_free(data, datalen); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +void +_libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa) +{ + if (!dsa) + return; + + BCryptDestroyKey(dsa->hKey); + dsa->hKey = NULL; + + _libssh2_wincng_safe_free(dsa->pbKeyObject, dsa->cbKeyObject); + _libssh2_wincng_safe_free(dsa, sizeof(libssh2_dsa_ctx)); +} +#endif + + +/*******************************************************************/ +/* + * Windows CNG backend: Key functions + */ + +#ifdef HAVE_LIBCRYPT32 +static unsigned long +_libssh2_wincng_pub_priv_write(unsigned char *key, + unsigned long offset, + const unsigned char *bignum, + const unsigned long length) +{ + _libssh2_htonu32(key + offset, length); + offset += 4; + + memcpy(key + offset, bignum, length); + offset += length; + + return offset; +} + +static int +_libssh2_wincng_pub_priv_keyfile_parse(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + unsigned char *pbEncoded, + unsigned long cbEncoded) +{ + unsigned char **rpbDecoded; + unsigned long *rcbDecoded; + unsigned char *key = NULL, *mth = NULL; + unsigned long keylen = 0, mthlen = 0; + unsigned long index, offset, length; + int ret; + + ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded, + &rpbDecoded, &rcbDecoded, &length); + + _libssh2_wincng_safe_free(pbEncoded, cbEncoded); + + if (ret) { + return -1; + } + + + if (length == 9) { /* private RSA key */ + mthlen = 7; + mth = LIBSSH2_ALLOC(session, mthlen); + if (mth) { + memcpy(mth, "ssh-rsa", mthlen); + } else { + ret = -1; + } + + + keylen = 4 + mthlen + 4 + rcbDecoded[2] + 4 + rcbDecoded[1]; + key = LIBSSH2_ALLOC(session, keylen); + if (key) { + offset = _libssh2_wincng_pub_priv_write(key, 0, mth, mthlen); + + offset = _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[2], + rcbDecoded[2]); + + _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[1], + rcbDecoded[1]); + } else { + ret = -1; + } + + } else if (length == 6) { /* private DSA key */ + mthlen = 7; + mth = LIBSSH2_ALLOC(session, mthlen); + if (mth) { + memcpy(mth, "ssh-dss", mthlen); + } else { + ret = -1; + } + + keylen = 4 + mthlen + 4 + rcbDecoded[1] + 4 + rcbDecoded[2] + + 4 + rcbDecoded[3] + 4 + rcbDecoded[4]; + key = LIBSSH2_ALLOC(session, keylen); + if (key) { + offset = _libssh2_wincng_pub_priv_write(key, 0, mth, mthlen); + + offset = _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[1], + rcbDecoded[1]); + + offset = _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[2], + rcbDecoded[2]); + + offset = _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[3], + rcbDecoded[3]); + + _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[4], + rcbDecoded[4]); + } else { + ret = -1; + } + + } else { + ret = -1; + } + + + for (index = 0; index < length; index++) { + _libssh2_wincng_safe_free(rpbDecoded[index], rcbDecoded[index]); + rpbDecoded[index] = NULL; + rcbDecoded[index] = 0; + } + + free(rpbDecoded); + free(rcbDecoded); + + + if (ret) { + if (mth) + LIBSSH2_FREE(session, mth); + if (key) + LIBSSH2_FREE(session, key); + } else { + *method = mth; + *method_len = mthlen; + *pubkeydata = key; + *pubkeydata_len = keylen; + } + + return ret; +} +#endif /* HAVE_LIBCRYPT32 */ + +int +_libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + ret = _libssh2_wincng_load_private(session, privatekey, passphrase, + &pbEncoded, &cbEncoded, 1, 1); + if (ret) { + return -1; + } + + return _libssh2_wincng_pub_priv_keyfile_parse(session, method, method_len, + pubkeydata, pubkeydata_len, + pbEncoded, cbEncoded); +#else + (void)method; + (void)method_len; + (void)pubkeydata; + (void)pubkeydata_len; + (void)privatekey; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to load public key from private key file: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + ret = _libssh2_wincng_load_private_memory(session, privatekeydata, + privatekeydata_len, passphrase, + &pbEncoded, &cbEncoded, 1, 1); + if (ret) { + return -1; + } + + return _libssh2_wincng_pub_priv_keyfile_parse(session, method, method_len, + pubkeydata, pubkeydata_len, + pbEncoded, cbEncoded); +#else + (void)method; + (void)method_len; + (void)pubkeydata_len; + (void)pubkeydata; + (void)privatekeydata; + (void)privatekeydata_len; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract public key from private key in memory: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +/*******************************************************************/ +/* + * Windows CNG backend: Cipher functions + */ + +int +_libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + unsigned char *iv, + unsigned char *secret, + int encrypt) +{ + BCRYPT_KEY_HANDLE hKey; + BCRYPT_KEY_DATA_BLOB_HEADER *header; + unsigned char *pbKeyObject, *pbIV, *key; + unsigned long dwKeyObject, dwIV, dwBlockLength, cbData, keylen; + int ret; + + (void)encrypt; + + ret = BCryptGetProperty(*type.phAlg, BCRYPT_OBJECT_LENGTH, + (unsigned char *)&dwKeyObject, + sizeof(dwKeyObject), + &cbData, 0); + if (!BCRYPT_SUCCESS(ret)) { + return -1; + } + + ret = BCryptGetProperty(*type.phAlg, BCRYPT_BLOCK_LENGTH, + (unsigned char *)&dwBlockLength, + sizeof(dwBlockLength), + &cbData, 0); + if (!BCRYPT_SUCCESS(ret)) { + return -1; + } + + pbKeyObject = malloc(dwKeyObject); + if (!pbKeyObject) { + return -1; + } + + + keylen = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + type.dwKeyLength; + key = malloc(keylen); + if (!key) { + free(pbKeyObject); + return -1; + } + + + header = (BCRYPT_KEY_DATA_BLOB_HEADER *)key; + header->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; + header->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; + header->cbKeyData = type.dwKeyLength; + + memcpy(key + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), + secret, type.dwKeyLength); + + ret = BCryptImportKey(*type.phAlg, NULL, BCRYPT_KEY_DATA_BLOB, &hKey, + pbKeyObject, dwKeyObject, key, keylen, 0); + + _libssh2_wincng_safe_free(key, keylen); + + if (!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(pbKeyObject, dwKeyObject); + return -1; + } + + if (type.dwUseIV) { + pbIV = malloc(dwBlockLength); + if (!pbIV) { + BCryptDestroyKey(hKey); + _libssh2_wincng_safe_free(pbKeyObject, dwKeyObject); + return -1; + } + dwIV = dwBlockLength; + memcpy(pbIV, iv, dwIV); + } else { + pbIV = NULL; + dwIV = 0; + } + + + ctx->hKey = hKey; + ctx->pbKeyObject = pbKeyObject; + ctx->pbIV = pbIV; + ctx->dwKeyObject = dwKeyObject; + ctx->dwIV = dwIV; + ctx->dwBlockLength = dwBlockLength; + + return 0; +} + +int +_libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + int encrypt, + unsigned char *block, + size_t blocklen) +{ + unsigned char *pbOutput; + unsigned long cbOutput, cbInput; + int ret; + + (void)type; + + cbInput = (unsigned long)blocklen; + + if (encrypt) { + ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL, + ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); + } else { + ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL, + ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); + } + if (BCRYPT_SUCCESS(ret)) { + pbOutput = malloc(cbOutput); + if (pbOutput) { + if (encrypt) { + ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL, + ctx->pbIV, ctx->dwIV, + pbOutput, cbOutput, &cbOutput, 0); + } else { + ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL, + ctx->pbIV, ctx->dwIV, + pbOutput, cbOutput, &cbOutput, 0); + } + if (BCRYPT_SUCCESS(ret)) { + memcpy(block, pbOutput, cbOutput); + } + + _libssh2_wincng_safe_free(pbOutput, cbOutput); + } else + ret = STATUS_NO_MEMORY; + } + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +void +_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx) +{ + BCryptDestroyKey(ctx->hKey); + ctx->hKey = NULL; + + _libssh2_wincng_safe_free(ctx->pbKeyObject, ctx->dwKeyObject); + ctx->pbKeyObject = NULL; + ctx->dwKeyObject = 0; + + _libssh2_wincng_safe_free(ctx->pbIV, ctx->dwBlockLength); + ctx->pbIV = NULL; + ctx->dwBlockLength = 0; +} + + +/*******************************************************************/ +/* + * Windows CNG backend: BigNumber functions + */ + +_libssh2_bn * +_libssh2_wincng_bignum_init(void) +{ + _libssh2_bn *bignum; + + bignum = (_libssh2_bn *)malloc(sizeof(_libssh2_bn)); + if (bignum) { + bignum->bignum = NULL; + bignum->length = 0; + } + + return bignum; +} + +static int +_libssh2_wincng_bignum_resize(_libssh2_bn *bn, unsigned long length) +{ + unsigned char *bignum; + + if (!bn) + return -1; + + if (length == bn->length) + return 0; + +#ifdef LIBSSH2_CLEAR_MEMORY + if (bn->bignum && bn->length > 0 && length < bn->length) { + SecureZeroMemory(bn->bignum + length, bn->length - length); + } +#endif + + bignum = realloc(bn->bignum, length); + if (!bignum) + return -1; + + bn->bignum = bignum; + bn->length = length; + + return 0; +} + +int +_libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom) +{ + unsigned char *bignum; + unsigned long length; + + if (!rnd) + return -1; + + length = (unsigned long)(ceil((float)bits / 8) * sizeof(unsigned char)); + if (_libssh2_wincng_bignum_resize(rnd, length)) + return -1; + + bignum = rnd->bignum; + + if (_libssh2_wincng_random(bignum, length)) + return -1; + + /* calculate significant bits in most significant byte */ + bits %= 8; + + /* fill most significant byte with zero padding */ + bignum[0] &= (1 << (8 - bits)) - 1; + + /* set some special last bits in most significant byte */ + if (top == 0) + bignum[0] |= (1 << (7 - bits)); + else if (top == 1) + bignum[0] |= (3 << (6 - bits)); + + /* make odd by setting first bit in least significant byte */ + if (bottom) + bignum[length - 1] |= 1; + + return 0; +} + +int +_libssh2_wincng_bignum_mod_exp(_libssh2_bn *r, + _libssh2_bn *a, + _libssh2_bn *p, + _libssh2_bn *m, + _libssh2_bn_ctx *bnctx) +{ + BCRYPT_KEY_HANDLE hKey; + BCRYPT_RSAKEY_BLOB *rsakey; + unsigned char *key, *bignum; + unsigned long keylen, offset, length; + int ret; + + (void)bnctx; + + if (!r || !a || !p || !m) + return -1; + + offset = sizeof(BCRYPT_RSAKEY_BLOB); + keylen = offset + p->length + m->length; + + key = malloc(keylen); + if (!key) + return -1; + + + /* https://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ + rsakey = (BCRYPT_RSAKEY_BLOB *)key; + rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; + rsakey->BitLength = m->length * 8; + rsakey->cbPublicExp = p->length; + rsakey->cbModulus = m->length; + rsakey->cbPrime1 = 0; + rsakey->cbPrime2 = 0; + + memcpy(key + offset, p->bignum, p->length); + offset += p->length; + + memcpy(key + offset, m->bignum, m->length); + + ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, + BCRYPT_RSAPUBLIC_BLOB, &hKey, key, keylen, + BCRYPT_NO_KEY_VALIDATION); + + if (BCRYPT_SUCCESS(ret)) { + ret = BCryptEncrypt(hKey, a->bignum, a->length, NULL, NULL, 0, + NULL, 0, &length, BCRYPT_PAD_NONE); + if (BCRYPT_SUCCESS(ret)) { + if (!_libssh2_wincng_bignum_resize(r, length)) { + length = max(a->length, length); + bignum = malloc(length); + if (bignum) { + offset = length - a->length; + memset(bignum, 0, offset); + memcpy(bignum + offset, a->bignum, a->length); + + ret = BCryptEncrypt(hKey, bignum, length, NULL, NULL, 0, + r->bignum, r->length, &offset, + BCRYPT_PAD_NONE); + + _libssh2_wincng_safe_free(bignum, length); + + if (BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_bignum_resize(r, offset); + } + } else + ret = STATUS_NO_MEMORY; + } else + ret = STATUS_NO_MEMORY; + } + + BCryptDestroyKey(hKey); + } + + _libssh2_wincng_safe_free(key, keylen); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +int +_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word) +{ + unsigned long offset, number, bits, length; + + if (!bn) + return -1; + + bits = 0; + number = word; + while (number >>= 1) + bits++; + + length = (unsigned long) (ceil(((double)(bits + 1)) / 8.0) * + sizeof(unsigned char)); + if (_libssh2_wincng_bignum_resize(bn, length)) + return -1; + + for (offset = 0; offset < length; offset++) + bn->bignum[offset] = (word >> (offset * 8)) & 0xff; + + return 0; +} + +unsigned long +_libssh2_wincng_bignum_bits(const _libssh2_bn *bn) +{ + unsigned char number; + unsigned long offset, length, bits; + + if (!bn) + return 0; + + length = bn->length - 1; + + offset = 0; + while (!(*(bn->bignum + offset)) && (offset < length)) + offset++; + + bits = (length - offset) * 8; + number = bn->bignum[offset]; + + while (number >>= 1) + bits++; + + bits++; + + return bits; +} + +void +_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len, + const unsigned char *bin) +{ + unsigned char *bignum; + unsigned long offset, length, bits; + + if (!bn || !bin || !len) + return; + + if (_libssh2_wincng_bignum_resize(bn, len)) + return; + + memcpy(bn->bignum, bin, len); + + bits = _libssh2_wincng_bignum_bits(bn); + length = (unsigned long) (ceil(((double)bits) / 8.0) * + sizeof(unsigned char)); + + offset = bn->length - length; + if (offset > 0) { + memmove(bn->bignum, bn->bignum + offset, length); + +#ifdef LIBSSH2_CLEAR_MEMORY + SecureZeroMemory(bn->bignum + length, offset); +#endif + + bignum = realloc(bn->bignum, length); + if (bignum) { + bn->bignum = bignum; + bn->length = length; + } + } +} + +void +_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin) +{ + if (bin && bn && bn->bignum && bn->length > 0) { + memcpy(bin, bn->bignum, bn->length); + } +} + +void +_libssh2_wincng_bignum_free(_libssh2_bn *bn) +{ + if (bn) { + if (bn->bignum) { + _libssh2_wincng_safe_free(bn->bignum, bn->length); + bn->bignum = NULL; + } + bn->length = 0; + _libssh2_wincng_safe_free(bn, sizeof(_libssh2_bn)); + } +} + + +/* + * Windows CNG backend: other functions + */ + +void _libssh2_init_aes_ctr(void) +{ + /* no implementation */ + (void)0; +} + +#endif /* LIBSSH2_WINCNG */ diff --git a/libssh2/src/wincng.h b/libssh2/src/wincng.h new file mode 100644 index 000000000..5219db7f8 --- /dev/null +++ b/libssh2/src/wincng.h @@ -0,0 +1,551 @@ +/* + * Copyright (C) 2013-2015 Marc Hoersken + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 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. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +/* required for cross-compilation against the w64 mingw-runtime package */ +#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) +#undef _WIN32_WINNT +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 +#endif + +#include +#include + + +#define LIBSSH2_MD5 1 + +#define LIBSSH2_HMAC_RIPEMD 0 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#define LIBSSH2_AES 1 +#define LIBSSH2_AES_CTR 0 +#define LIBSSH2_BLOWFISH 0 +#define LIBSSH2_RC4 1 +#define LIBSSH2_CAST 0 +#define LIBSSH2_3DES 1 + +#define LIBSSH2_RSA 1 +#define LIBSSH2_DSA 1 + +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 +#define SHA512_DIGEST_LENGTH 64 + + +/*******************************************************************/ +/* + * Windows CNG backend: Global context handles + */ + +struct _libssh2_wincng_ctx { + BCRYPT_ALG_HANDLE hAlgRNG; + BCRYPT_ALG_HANDLE hAlgHashMD5; + BCRYPT_ALG_HANDLE hAlgHashSHA1; + BCRYPT_ALG_HANDLE hAlgHashSHA256; + BCRYPT_ALG_HANDLE hAlgHashSHA512; + BCRYPT_ALG_HANDLE hAlgHmacMD5; + BCRYPT_ALG_HANDLE hAlgHmacSHA1; + BCRYPT_ALG_HANDLE hAlgHmacSHA256; + BCRYPT_ALG_HANDLE hAlgHmacSHA512; + BCRYPT_ALG_HANDLE hAlgRSA; + BCRYPT_ALG_HANDLE hAlgDSA; + BCRYPT_ALG_HANDLE hAlgAES_CBC; + BCRYPT_ALG_HANDLE hAlgRC4_NA; + BCRYPT_ALG_HANDLE hAlg3DES_CBC; +}; + +struct _libssh2_wincng_ctx _libssh2_wincng; + + +/*******************************************************************/ +/* + * Windows CNG backend: Generic functions + */ + +void _libssh2_wincng_init(void); +void _libssh2_wincng_free(void); + +#define libssh2_crypto_init() \ + _libssh2_wincng_init() +#define libssh2_crypto_exit() \ + _libssh2_wincng_free() + +#define _libssh2_random(buf, len) \ + _libssh2_wincng_random(buf, len) + +#define libssh2_prepare_iovec(vec, len) /* Empty. */ + + +/*******************************************************************/ +/* + * Windows CNG backend: Hash structure + */ + +typedef struct __libssh2_wincng_hash_ctx { + BCRYPT_HASH_HANDLE hHash; + unsigned char *pbHashObject; + unsigned long dwHashObject; + unsigned long cbHash; +} _libssh2_wincng_hash_ctx; + +/* + * Windows CNG backend: Hash functions + */ + +#define libssh2_sha1_ctx _libssh2_wincng_hash_ctx +#define libssh2_sha1_init(ctx) \ + (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \ + SHA_DIGEST_LENGTH, NULL, 0) == 0) +#define libssh2_sha1_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha1_final(ctx, hash) \ + _libssh2_wincng_hash_final(&ctx, hash) +#define libssh2_sha1(data, datalen, hash) \ + _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \ + hash, SHA_DIGEST_LENGTH) + +#define libssh2_sha256_ctx _libssh2_wincng_hash_ctx +#define libssh2_sha256_init(ctx) \ + (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \ + SHA256_DIGEST_LENGTH, NULL, 0) == 0) +#define libssh2_sha256_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha256_final(ctx, hash) \ + _libssh2_wincng_hash_final(&ctx, hash) +#define libssh2_sha256(data, datalen, hash) \ + _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA256, \ + hash, SHA256_DIGEST_LENGTH) + +#define libssh2_sha512_ctx _libssh2_wincng_hash_ctx +#define libssh2_sha512_init(ctx) \ + (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \ + SHA512_DIGEST_LENGTH, NULL, 0) == 0) +#define libssh2_sha512_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha512_final(ctx, hash) \ + _libssh2_wincng_hash_final(&ctx, hash) +#define libssh2_sha512(data, datalen, hash) \ + _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA512, \ + hash, SHA512_DIGEST_LENGTH) + +#define libssh2_md5_ctx _libssh2_wincng_hash_ctx +#define libssh2_md5_init(ctx) \ + (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \ + MD5_DIGEST_LENGTH, NULL, 0) == 0) +#define libssh2_md5_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_md5_final(ctx, hash) \ + _libssh2_wincng_hash_final(&ctx, hash) +#define libssh2_md5(data, datalen, hash) \ + _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashMD5, \ + hash, MD5_DIGEST_LENGTH) + +/* + * Windows CNG backend: HMAC functions + */ + +#define libssh2_hmac_ctx _libssh2_wincng_hash_ctx +#define libssh2_hmac_ctx_init(ctx) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA1, \ + SHA_DIGEST_LENGTH, key, keylen) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacMD5, \ + MD5_DIGEST_LENGTH, key, keylen) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) + /* not implemented */ +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA256, \ + SHA256_DIGEST_LENGTH, key, keylen) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA512, \ + SHA512_DIGEST_LENGTH, key, keylen) +#define libssh2_hmac_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_hmac_final(ctx, hash) \ + _libssh2_wincng_hmac_final(&ctx, hash) +#define libssh2_hmac_cleanup(ctx) \ + _libssh2_wincng_hmac_cleanup(ctx) + + +/*******************************************************************/ +/* + * Windows CNG backend: Key Context structure + */ + +typedef struct __libssh2_wincng_key_ctx { + BCRYPT_KEY_HANDLE hKey; + unsigned char *pbKeyObject; + unsigned long cbKeyObject; +} _libssh2_wincng_key_ctx; + + +/* + * Windows CNG backend: RSA functions + */ + +#define libssh2_rsa_ctx _libssh2_wincng_key_ctx +#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \ + d, d_len, p, p_len, q, q_len, \ + e1, e1_len, e2, e2_len, c, c_len) \ + _libssh2_wincng_rsa_new(rsactx, e, e_len, n, n_len, \ + d, d_len, p, p_len, q, q_len, \ + e1, e1_len, e2, e2_len, c, c_len) +#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \ + _libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase) +#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \ + filedata_len, passphrase) \ + _libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \ + filedata_len, passphrase) +#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \ + _libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) +#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \ + _libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) +#define _libssh2_rsa_free(rsactx) \ + _libssh2_wincng_rsa_free(rsactx) + +/* + * Windows CNG backend: DSA functions + */ + +#define libssh2_dsa_ctx _libssh2_wincng_key_ctx +#define _libssh2_dsa_new(dsactx, p, p_len, q, q_len, \ + g, g_len, y, y_len, x, x_len) \ + _libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \ + g, g_len, y, y_len, x, x_len) +#define _libssh2_dsa_new_private(dsactx, s, filename, passphrase) \ + _libssh2_wincng_dsa_new_private(dsactx, s, filename, passphrase) +#define _libssh2_dsa_new_private_frommemory(dsactx, s, filedata, \ + filedata_len, passphrase) \ + _libssh2_wincng_dsa_new_private_frommemory(dsactx, s, filedata, \ + filedata_len, passphrase) +#define _libssh2_dsa_sha1_sign(dsactx, hash, hash_len, sig) \ + _libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig) +#define _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len) \ + _libssh2_wincng_dsa_sha1_verify(dsactx, sig, m, m_len) +#define _libssh2_dsa_free(dsactx) \ + _libssh2_wincng_dsa_free(dsactx) + +/* + * Windows CNG backend: Key functions + */ + +#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \ + _libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) +#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ + pk, pk_len, pw) \ + _libssh2_wincng_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ + pk, pk_len, pw) + + +/*******************************************************************/ +/* + * Windows CNG backend: Cipher Context structure + */ + +struct _libssh2_wincng_cipher_ctx { + BCRYPT_KEY_HANDLE hKey; + unsigned char *pbKeyObject; + unsigned char *pbIV; + unsigned long dwKeyObject; + unsigned long dwIV; + unsigned long dwBlockLength; +}; + +#define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx + +/* + * Windows CNG backend: Cipher Type structure + */ + +struct _libssh2_wincng_cipher_type { + BCRYPT_ALG_HANDLE *phAlg; + unsigned long dwKeyLength; + unsigned long dwUseIV; +}; + +#define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type + +#define _libssh2_cipher_aes256ctr { NULL, 32, 1 } /* not supported */ +#define _libssh2_cipher_aes192ctr { NULL, 24, 1 } /* not supported */ +#define _libssh2_cipher_aes128ctr { NULL, 16, 1 } /* not supported */ +#define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1 } +#define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1 } +#define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1 } +#define _libssh2_cipher_blowfish { NULL, 16, 0 } /* not supported */ +#define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0 } +#define _libssh2_cipher_cast5 { NULL, 16, 0 } /* not supported */ +#define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1 } + +/* + * Windows CNG backend: Cipher functions + */ + +#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \ + _libssh2_wincng_cipher_init(ctx, type, iv, secret, encrypt) +#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen) \ + _libssh2_wincng_cipher_crypt(ctx, type, encrypt, block, blocklen) +#define _libssh2_cipher_dtor(ctx) \ + _libssh2_wincng_cipher_dtor(ctx) + +/*******************************************************************/ +/* + * Windows CNG backend: BigNumber Context + */ + +#define _libssh2_bn_ctx int /* not used */ +#define _libssh2_bn_ctx_new() 0 /* not used */ +#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */ + + +/*******************************************************************/ +/* + * Windows CNG backend: BigNumber structure + */ + +struct _libssh2_wincng_bignum { + unsigned char *bignum; + unsigned long length; +}; + +#define _libssh2_bn struct _libssh2_wincng_bignum + +/* + * Windows CNG backend: BigNumber functions + */ + +_libssh2_bn *_libssh2_wincng_bignum_init(void); + +#define _libssh2_bn_init() \ + _libssh2_wincng_bignum_init() +#define _libssh2_bn_init_from_bin() \ + _libssh2_bn_init() +#define _libssh2_bn_rand(bn, bits, top, bottom) \ + _libssh2_wincng_bignum_rand(bn, bits, top, bottom) +#define _libssh2_bn_mod_exp(r, a, p, m, ctx) \ + _libssh2_wincng_bignum_mod_exp(r, a, p, m, ctx) +#define _libssh2_bn_set_word(bn, word) \ + _libssh2_wincng_bignum_set_word(bn, word) +#define _libssh2_bn_from_bin(bn, len, bin) \ + _libssh2_wincng_bignum_from_bin(bn, len, bin) +#define _libssh2_bn_to_bin(bn, bin) \ + _libssh2_wincng_bignum_to_bin(bn, bin) +#define _libssh2_bn_bytes(bn) bn->length +#define _libssh2_bn_bits(bn) \ + _libssh2_wincng_bignum_bits(bn) +#define _libssh2_bn_free(bn) \ + _libssh2_wincng_bignum_free(bn) + +/*******************************************************************/ +/* + * Windows CNG backend: forward declarations + */ +void _libssh2_wincng_init(void); +void _libssh2_wincng_free(void); +int _libssh2_wincng_random(void *buf, int len); +void _libssh2_init_aes_ctr(void); + +int +_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, + BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen, + unsigned char *key, unsigned long keylen); +int +_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, + const unsigned char *data, unsigned long datalen); +int +_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx, + unsigned char *hash); +int +_libssh2_wincng_hash(unsigned char *data, unsigned long datalen, + BCRYPT_ALG_HANDLE hAlg, + unsigned char *hash, unsigned long hashlen); + +int +_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx, + unsigned char *hash); +void +_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx); + +int +_libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len, + unsigned long flags); + +int +_libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen); +int +_libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase); +int +_libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); +int +_libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len); +int +_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len); +void +_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa); + +#if LIBSSH2_DSA +int +_libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *gdata, + unsigned long glen, + const unsigned char *ydata, + unsigned long ylen, + const unsigned char *xdata, + unsigned long xlen); +int +_libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase); +int +_libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); +int +_libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa, + const unsigned char *sig_fixed, + const unsigned char *m, + unsigned long m_len); +int +_libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa, + const unsigned char *hash, + unsigned long hash_len, + unsigned char *sig_fixed); +void +_libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa); +#endif + +int +_libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase); +int +_libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase); + +int +_libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + unsigned char *iv, + unsigned char *secret, + int encrypt); +int +_libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + int encrypt, + unsigned char *block, + size_t blocklen); +void +_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx); + +_libssh2_bn * +_libssh2_wincng_bignum_init(void); +int +_libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom); +int +_libssh2_wincng_bignum_mod_exp(_libssh2_bn *r, + _libssh2_bn *a, + _libssh2_bn *p, + _libssh2_bn *m, + _libssh2_bn_ctx *bnctx); +int +_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word); +unsigned long +_libssh2_wincng_bignum_bits(const _libssh2_bn *bn); +void +_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len, + const unsigned char *bin); +void +_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin); +void +_libssh2_wincng_bignum_free(_libssh2_bn *bn); diff --git a/libssh2/test-driver b/libssh2/test-driver new file mode 100644 index 000000000..32bf39e83 --- /dev/null +++ b/libssh2/test-driver @@ -0,0 +1,127 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2012-06-27.10; # UTC + +# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <$log_file 2>&1 +estatus=$? +if test $enable_hard_errors = no && test $estatus -eq 99; then + estatus=1 +fi + +case $estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libssh2/vms/libssh2_config.h b/libssh2/vms/libssh2_config.h new file mode 100644 index 000000000..b8f73e272 --- /dev/null +++ b/libssh2/vms/libssh2_config.h @@ -0,0 +1,88 @@ +#ifndef LIBSSH2_CONFIG_H +#ifdef __VMS + +#define LIBSSH2_CONFIG_H + +/* VMS specific libssh2_config.h + */ + +#define ssize_t SSIZE_T + +typedef unsigned int uint32_t ; +typedef unsigned int socklen_t; /* missing in headers on VMS */ + +/* Have's */ + +#define HAVE_UNISTD_H +#define HAVE_STDLIB_H +#define HAVE_INTTYPES_H +#define HAVE_SYS_TIME_H +#define HAVE_SELECT +#define HAVE_UIO + +#define HAVE_SYS_SOCKET.H +#define HAVE_NETINET_IN_H +#define HAVE_ARPA_INET_H + +#define HAVE_GETTIMEOFDAY 1 + +#define POSIX_C_SOURCE + +/* Enable the possibility of using tracing */ + +#define LIBSSH2DEBUG 1 + +/* For selection of proper block/unblock function in session.c */ + +#define HAVE_FIONBIO + +#include + +/* In VMS TCP/IP Services and some BSD variants SO_STATE retrieves + * a bitmask revealing amongst others the blocking state of the + * socket. On VMS the bits are undocumented, but SS_NBIO + * works, I did not test the other bits. Below bitdefs are + * from Berkely source socketvar.h at + * http://ftp.fibranet.cat/UnixArchive/PDP-11/Trees/2.11BSD/sys/h/socketvar.h + * Socket state bits. + * #define SS_NOFDREF 0x001 no file table ref any more + * #define SS_ISCONNECTED 0x002 socket connected to a peer + * #define SS_ISCONNECTING 0x004 in process of connecting to peer + * #define SS_ISDISCONNECTING 0x008 in process of disconnecting + * #define SS_CANTSENDMORE 0x010 can't send more data to peer + * #define SS_CANTRCVMORE 0x020 can't receive more data from peer + * #define SS_RCVATMARK 0x040 at mark on input + * #define SS_PRIV 0x080 privileged for broadcast, raw... + * #define SS_NBIO 0x100 non-blocking ops + * #define SS_ASYNC 0x200 async i/o notify + * + */ + +#ifdef SO_STATE + +/* SO_STATE is defined in stropts.h by DECC + * When running on Multinet, SO_STATE renders a protocol + * not started error. Functionally this has no impact, + * apart from libssh2 not being able to restore the socket + * to the proper blocking/non-blocking state. + */ + +#define SS_NBIO 0x100 + +#endif + +/* Use OpenSSL */ +#define LIBSSH2_OPENSSL 1 + +/* Compile in zlib support. We link against gnv$libzshr, as available + * from https://sourceforge.net/projects/vms-ports/files/. + */ + +#define LIBSSH2_HAVE_ZLIB + +/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ + +#define LIBSSH2_DH_GEX_NEW 1 + +#endif /* __VMS */ +#endif /* LIBSSH2_CONFIG_H */ diff --git a/libssh2/vms/libssh2_make_example.dcl b/libssh2/vms/libssh2_make_example.dcl new file mode 100644 index 000000000..af4116dd5 --- /dev/null +++ b/libssh2/vms/libssh2_make_example.dcl @@ -0,0 +1,125 @@ +$! +$! +$ olddir = f$environment("default") +$ on control_y then goto YExit +$! +$ gosub Init +$ if .not. init_status then goto YExit +$! +$ if what .eqs. "ALL" +$ then +$ call MakeAll +$ else +$ call Make +$endif +$! +$YExit: +$ set noon +$! deassign exadir +$! deassign objdir +$ delete 'link_opts';* +$ set default 'olddir' +$exit + +$MakeAll: subroutine +$! +$ set noon +$Loop: +$ this = f$search("exadir:*.c;0") +$ if this .eqs. "" then goto EndLoop +$! +$ what = f$parse( this,,,"name") +$ if what .eqs. "x11" then goto loop ! not portable yet +$ call Make +$! +$ goto Loop +$EndLoop: +$! +$exit +$endsubroutine + + +$Make: subroutine +$! +$ set noon +$! +$ cc 'cc_include' 'cc_flags'/object=objdir:'what' exadir:'what' +$ sev = $severity +$ if sev .and. 2 +$ then +$ say "Error compiling ''what', not linked." +$ else +$ if .not. (sev .and. 1) +$ then +$ say "Compile warnings in ''what'" +$ endif +$ link/exe='what'.exe objdir:'what'.obj, 'link_opts'/opt +$ endif +$! +$! +$End: +$ delete objdir:'what'.obj;* +$exit +$endsubroutine + + +$Init: +$! +$! +$ init_status = 1 +$ thisid = f$integer( %x'f$getjpi(0,"pid")') + "''f$cvtime(,,"second")'" +$ mdir = f$environment("procedure") +$ mdir = mdir - f$parse(mdir,,,"name") - f$parse(mdir,,,"type") - f$parse(mdir,,,"version") +$ set default 'mdir' +$! +$ objdir = "[.example_objects]" +$ exadir = "[-.example]" +$! +$ objdirfile = objdir - "[." - "]" + ".dir" +$ if f$search( objdirfile ) .eqs. "" +$ then +$ create/directory 'objdir' +$ endif +$! +$ define objdir 'objdir' +$ define exadir 'exadir' +$! +$ cc_include = "/include=([],[-.include])" +$ cc_flags = "/name=shortened/show=all/define=(_USE_STD_STAT=1)" +$ link_opts = "objdir:libssh2_''thisid'.opt" +$! +$! +$ what = "''p1'" +$ if what .eqs. "" .or. f$edit(p1,"trim,collapse,upcase") .eqs. "ALL" +$ then +$ what = "ALL" +$ else +$ what = f$parse(what,,,"name") +$ if f$search("exadir:''what'.c") .eqs. "" +$ then +$ write sys$output "Can't make ''what'" +$ init_status = 0 +$ endif +$ endif +$! +$ currentlib = f$search("libssh2*.exe") +$! +$ define libssh2 'currentlib' +$! +$ how = "''p2'" +$ if how .eqs. "" .or. f$edit(p2,"trim,collapse,upcase") .eqs. "STATIC" +$ then +$ open/write lout 'link_opts' +$ write lout "libssh2.olb/lib" +$ write lout "sys$share:ssl$libcrypto_shr32.exe/share" +$ write lout "sys$share:ssl$libssl_shr32.exe/share" +$ write lout "gnv$libzshr/share" +$ close lout +$ else +$ how = "SHARED" +$ open/write lout 'link_opts' +$ write lout "libssh2/share" +$ close lout +$ endif +$! +$return diff --git a/libssh2/vms/libssh2_make_help.dcl b/libssh2/vms/libssh2_make_help.dcl new file mode 100644 index 000000000..b36512ecb --- /dev/null +++ b/libssh2/vms/libssh2_make_help.dcl @@ -0,0 +1,95 @@ +$! +$! +$! +$ olddir = f$environment( "default" ) +$ on control_y then goto End +$ on error then goto End +$! +$ gosub Init +$! +$ man2help sys$input: libssh2.hlp -b 1 + +LIBSSH2 + +OpenVMS port of the libssh2 library, which provides an +API to implement client SSH communication. + +License information is available at the Copying subtopic. + +$! +$ open/append mh libssh2.hlp +$ write mh helpversion +$ close mh +$! +$ man2help -a [-]README.; libssh2.hlp -b 2 +$ man2help -a [-]COPYING.; libssh2.hlp -b 2 +$ man2help -a [-]NEWS.; libssh2.hlp -b 2 +$ man2help -a [-]RELEASE-NOTES.; libssh2.hlp -b 2 +$ man2help -a [-.docs]AUTHORS.; libssh2.hlp -b 2 +$ man2help -a [-.docs]BINDINGS.; libssh2.hlp -b 2 +$ man2help -a [-.docs]HACKING.; libssh2.hlp -b 2 +$ if f$search("[]HACKING_CRYPTO.") .nes. "" then delete []HACKING_CRYPTO.;* +$ copy [-.docs]HACKING.CRYPTO; []HACKING_CRYPTO. +$ man2help -a []HACKING_CRYPTO.; libssh2.hlp -b 2 +$ man2help -a [-.docs]TODO.; libssh2.hlp -b 2 +$! +$ man2help -a sys$input: libssh2.hlp -b 2 + +API_Reference + +Reference of all implemented API calls in +libssh2. + +$! +$ man2help -a [-.docs]*.3 libssh2.hlp -b 3 -p +$! +$ library/help/create libssh2.hlb libssh2.hlp +$! +$End: +$ set default 'olddir' +$exit +$! +$!------------------------------------------------------- +$! +$Init: +$! +$ thisdir = f$environment( "procedure" ) +$ thisdir = f$parse(thisdir,,,"device") + f$parse(thisdir,,,"directory") +$ set default 'thisdir' +$! +$ say = "write sys$output" +$! +$ pipe search [-.include]*.h libssh2_version_major/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; - + define/job majorv &l ) +$ pipe search [-.include]*.h libssh2_version_minor/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; - + define/job minorv &l ) +$ pipe search [-.include]*.h libssh2_version_patch/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; - + define/job patchv &l ) +$! +$ majorv = f$trnlnm("majorv") +$ minorv = f$integer(f$trnlnm("minorv")) +$ patchv = f$integer( f$trnlnm("patchv")) +$! +$ helpversion = "This help library is based on build version ''majorv'.''minorv'.''patchv' of libssh2." +$! +$ deassign/job majorv +$ deassign/job minorv +$ deassign/job patchv +$! +$ if f$search( "man2help.exe" ) .eqs. "" +$ then +$ cc man2help +$ link man2help +$ endif +$! +$ man2help := $'thisdir'man2help.exe +$! +$ if f$search("libssh2.hlp") .nes. "" +$ then +$ delete libssh2.hlp;* +$ endif +$ if f$search("libssh2.hlb") .nes. "" +$ then +$ delete libssh2.hlb;* +$ endif +$return diff --git a/libssh2/vms/libssh2_make_kit.dcl b/libssh2/vms/libssh2_make_kit.dcl new file mode 100644 index 000000000..6a1495880 --- /dev/null +++ b/libssh2/vms/libssh2_make_kit.dcl @@ -0,0 +1,222 @@ +$! +$ olddir = f$environment("default") +$ on error then goto End +$! +$ gosub Init +$! +$ call WriteProductDescriptionFile +$ call WriteProductTextFile +$! +$! backup tree +$! +$ backup [-...]*.*;0/excl=([]*.exe,*.obj,*.opt,*.hlp,*.hlb,*.bck,*.com,*.pcsi*) - + libssh2-'versionname''datename'_src.bck/save +$ purge libssh2-'versionname''datename'_src.bck +$! +$! backup examples +$! +$ backup [-.example]*.c;0 libssh2_examples-'versionname''datename'.bck/save +$ dire libssh2_examples-'versionname''datename'.bck +$ purge libssh2_examples-'versionname''datename'.bck +$! +$ set default [-] +$! +$ defdir = f$environment( "default" ) +$ thisdev = f$parse(defdir,,,"device","no_conceal") +$ thisdir = f$parse(defdir,,,"directory","no_conceal") - "][" - "][" - "][" - "][" +$! +$ libssh2_kf = thisdev + thisdir +$ libssh2_kf = libssh2_kf - "]" + ".]" +$! +$ set default 'mdir' +$! +$ define/translation_attributes=concealed libssh2_kf 'libssh2_kf' +$! +$ product package libssh2 - + /base='arch' - + /producer=jcb - + /source=[] - ! where to find PDF and PTF + /destination=[] - ! where to put .PCSI file + /material=libssh2_kf:[000000...] - ! where to find product material + /version="''vms_majorv'.''minorv'-''patchv'''datename'" - + /format=sequential +$! +$End: +$! +$ set noon +$ if f$search("*.pcsi$desc;*") .nes. "" then delete *.pcsi$desc;* +$ if f$search("*.pcsi$text;*") .nes. "" then delete *.pcsi$text;* +$ if f$search("libssh2-''versionname'''datename'_src.bck;*") .nes. "" then delete libssh2-'versionname''datename'_src.bck;* +$ if f$search("libssh2_examples-''versionname'''datename'.bck;*") .nes. "" then delete libssh2_examples-'versionname''datename'.bck;* +$! +$ if f$trnlnm("libssh2_kf") .nes. "" then deassign libssh2_kf +$ set default 'olddir' +$! +$exit +$! +$!-------------------------------------------------------------------------------- +$! +$Init: +$ set process/parse=extended +$! +$ say = "write sys$output" +$! +$ mdir = f$environment("procedure") +$ mdir = mdir - f$parse(mdir,,,"name") - f$parse(mdir,,,"type") - f$parse(mdir,,,"version") +$! +$ set default 'mdir' +$! +$ pipe search [-.include]*.h libssh2_version_major/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; - + define/job majorv &l ) +$ pipe search [-.include]*.h libssh2_version_minor/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; - + define/job minorv &l ) +$ pipe search [-.include]*.h libssh2_version_patch/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; - + define/job patchv &l ) +$! +$ majorv = f$trnlnm("majorv") +$ minorv = f$integer(f$trnlnm("minorv")) +$ patchv = f$integer( f$trnlnm("patchv")) +$! +$ deassign/job majorv +$ deassign/job minorv +$ deassign/job patchv +$! +$ vms_majorv = f$trnlnm("vms_majorv") +$ if vms_majorv .eqs. "" then vms_majorv = majorv +$! +$ arch = "UNKNOWN" +$ if f$getsyi("arch_type") .eq. 2 then arch = "AXPVMS" +$ if f$getsyi("arch_type") .eq. 3 then arch = "I64VMS" +$! +$ if arch .eqs. "UNKNOWN" +$ then +$ say "Unsupported or unknown architecture, only works on Alpha and Itanium" +$ exit 2 +$ endif +$! +$! is this a proper release or a daily snapshot? +$! crummy, but should work. +$! +$ daily = "TRUE" +$ firstdash = f$locate("-",mdir) +$ restdir = f$extract( firstdash + 1, 80, mdir) +$ seconddash = f$locate("-", restdir) +$ if seconddash .ge. f$length( restdir ) +$ then +$ daily = "FALSE" +$ datename = "Final" +$ else +$ datename = "D" + f$extract(seconddash+1,8,restdir) +$ endif +$! +$ if daily +$ then +$ productname = "JCB ''arch' LIBSSH2 V''vms_majorv'.''minorv'-''patchv'''datename'" +$ else +$ productname = "JCB ''arch' LIBSSH2 V''vms_majorv'.''minorv'-''patchv'''datename'" +$ endif +$! +$ productfilename = "JCB-''arch'-LIBSSH2-" + f$fao("V!2ZL!2ZL-!2ZL!AS-1", f$integer(vms_majorv),minorv,patchv,datename) +$! +$ versionname = "''vms_majorv'_''minorv'_''patchv'" +$! +$return +$! +$!-------------------------------------------------------------------------------- +$! +$WriteProductDescriptionFile: subroutine +$! +$ open/write pd 'productfilename'.PCSI$DESC +$! +$ write pd "product ''productname' full ;" +$ write pd " software DEC ''arch' VMS ;" +$ write pd " if (not ) ; +$ write pd " error NEED_VMS83 ;" +$ write pd " end if ;" +$ write pd " software HP ''arch' SSL version minimum V1.3;" +$ write pd " if (not ) ; +$ write pd " error NEED_SSL ;" +$ write pd " end if ;" +$ write pd " execute preconfigure (""set process/parse_type=extended"");" +$ write pd " execute postinstall (""set process/parse_type=extended""," +$ write pd " ""rename pcsi$destination:[gnv]usr.dir usr.DIR""," +$ write pd " ""rename pcsi$destination:[gnv.usr]include.dir include.DIR""," +$ write pd " ""rename pcsi$destination:[gnv.usr.include]libssh2.dir libssh2.DIR""," +$ write pd " ""rename pcsi$destination:[gnv.usr.include.libssh2]libssh2.h libssh2.h""," +$ write pd " ""rename pcsi$destination:[gnv.usr.include.libssh2]libssh2_publickey.h libssh2_publickey.h""," +$ write pd " ""rename pcsi$destination:[gnv.usr.include.libssh2]libssh2_sftp.h libssh2_sftp.h""," +$ write pd " ""rename pcsi$destination:[gnv.usr.include.libssh2]libssh2_config.h libssh2_config.h""," +$ write pd " ""rename pcsi$destination:[gnv.usr]lib.dir lib.DIR""," +$ write pd " ""rename pcsi$destination:[gnv.usr.lib]gnv$libssh2_''versionname'.exe gnv$libssh2_''versionname'.exe""," +$ write pd " ""rename pcsi$destination:[gnv.usr.share.doc.libssh2]libssh2.hlb libssh2.hlb"");" +$ write pd " information RELEASE_NOTES phase after ;" +$ write pd " option EXAMPLE default 0 ;" +$ write pd " directory ""[gnv.usr.share.doc.libssh2.examples]"" ;" +$ write pd " file ""[gnv.usr.share.doc.libssh2.examples]libssh2_examples-''versionname'''datename'.bck"";" +$ write pd " end option ;" +$ write pd " option SOURCE default 0 ;" +$ write pd " directory ""[gnv.common_src]"" ;" +$ write pd " file ""[gnv.common_src]libssh2-''versionname'''datename'_src.bck"";" +$ write pd " end option ;" +$ write pd " directory ""[gnv]"" ;" +$ write pd " directory ""[gnv.usr]"" ;" +$ write pd " directory ""[gnv.usr.lib]"" ;" +$ write pd " directory ""[gnv.usr.include]"" ;" +$ write pd " directory ""[gnv.usr.include.libssh2]"" ;" +$ write pd " directory ""[gnv.usr.share]"" ;" +$ write pd " directory ""[gnv.usr.share.doc]"" ;" +$ write pd " directory ""[gnv.usr.share.doc.libssh2]"" ;" +$ write pd " file ""[gnv.usr.include.libssh2]libssh2.h"" source ""[include]libssh2.h"";" +$ write pd " file ""[gnv.usr.include.libssh2]libssh2_publickey.h"" source ""[include]libssh2_publickey.h"";" +$ write pd " file ""[gnv.usr.include.libssh2]libssh2_sftp.h"" source ""[include]libssh2_sftp.h"";" +$ write pd " file ""[gnv.usr.include.libssh2]libssh2_config.h"" source ""[vms]libssh2_config.h"";" +$ write pd " file ""[gnv.usr.share.doc.libssh2]libssh2.hlb"" source ""[vms]libssh2.hlb"";" +$ write pd " file ""[gnv.usr.share.doc.libssh2]libssh2-''versionname'.news"" source ""[000000]NEWS."";" +$ write pd " file ""[gnv.usr.share.doc.libssh2]libssh2-''versionname'.release_notes"" source ""[vms]readme.vms"";" +$ write pd " file ""[gnv.usr.lib]gnv$libssh2_''versionname'.exe"" source ""[vms]libssh2_''versionname'.exe"";" +$ write pd "end product ;" +$ close pd +$exit +$endsubroutine +$! +$!-------------------------------------------------------------------------------- +$! +$WriteProductTextFile: subroutine +$! +$ open/write pt 'productfilename'.PCSI$TEXT +$ write pt "=PRODUCT ''productname' Full" +$ write pt "1 'PRODUCER" +$ write pt "=prompt libssh2 is an open source product ported to VMS by Jose Baars" +$ write pt "This software product is provided with no warranty." +$ write pt "For license information see the LIBSSH2 help library." +$ write pt "1 'PRODUCT" +$ write pt "=prompt JCB LIBSSH2 for OpenVMS" +$ write pt "" +$ write pt "libssh2 is an open source client side library that aims to implement" +$ write pt "the SSH protocol. This is the OpenVMS port of that library." +$ write pt "Further information at https://www.libssh2.org." +$ write pt "" +$ write pt "1 NEED_VMS83" +$ write pt "=prompt OpenVMS 8.3 or later is not installed on your system." +$ write pt "This product requires OpenVMS 8.3 or later to function." +$ write pt "" +$ write pt "1 NEED_SSL" +$ write pt "=prompt HP SSL 1.3 or later is not installed on your system." +$ write pt "This product requires HP SSL 1.3 or later to function." +$ write pt "" +$ write pt "1 RELEASE_NOTES" +$ write pt "=prompt Release notes and the libssh2 help library are available in [gnv.usr.share.doc.libssh2] directory." +$ write pt "" +$ write pt "1 EXAMPLE" +$ write pt "=prompt Do you want the libssh2 C programming examples ? " +$ write pt "The libssh2 coding examples will be available in backup saveset " +$ write pt "[gnv.usr.share.doc.libssh2.examples]libssh2_examples_''versionname'.bck" +$ write pt "" +$ write pt "1 SOURCE" +$ write pt "=prompt Do you want the complete libssh2 source tree ? " +$ write pt "The libssh2 source tree will be available in backup saveset " +$ write pt "[gnv.common_src]libssh2_''versionname'''datename'_src.bck" +$close pt +$exit +$ endsubroutine + diff --git a/libssh2/vms/libssh2_make_lib.dcl b/libssh2/vms/libssh2_make_lib.dcl new file mode 100644 index 000000000..56d168f21 --- /dev/null +++ b/libssh2/vms/libssh2_make_lib.dcl @@ -0,0 +1,345 @@ +$! +$! +$ olddir = f$environment("default") +$ on control_y then goto YExit +$! +$ gosub Init +$ if .not. init_status then goto YExit +$! +$ call CompileAll +$ call BuildTransferVectors +$ call LinkShared +$! +$ call Cleanup +$! +$YExit: +$ set noon +$! +$ deassign srcdir +$ if f$search("objdir:*.*;*") .nes. "" then delete objdir:*.*;* +$ deassign objdir +$ delete library_objects.dir;* +$! +$ set default 'olddir' +$exit +$! +$!--------------------------------------------------------------------- +$! +$Init: +$! +$! +$ init_status = 1 +$ thisid = f$integer( %x'f$getjpi(0,"pid")') +$ mdir = f$environment("procedure") +$ mdir = mdir - f$parse(mdir,,,"name") - f$parse(mdir,,,"type") - f$parse(mdir,,,"version") +$ set default 'mdir' +$! +$ objdir = "[.library_objects]" +$ srcdir = "[-.src]" +$! +$ objdirfile = objdir - "[." - "]" + ".dir" +$ if f$search( objdirfile ) .eqs. "" +$ then +$ create/directory 'objdir' +$ endif +$! +$ define objdir 'objdir' +$ define srcdir 'srcdir' +$! +$ cc_include = "/include=([],[-.include],""/gnv$zlib_include"")" +$ cc_define = "/DEFINE=(_USE_STD_STAT=1)" +$ link_opts = "objdir:libssh2_''thisid'.opt" +$! +$ pipe search [-.include]libssh2.h libssh2_version_major/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; - + define/job majorv &l ) +$ pipe search [-.include]libssh2.h libssh2_version_minor/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; - + define/job minorv &l ) +$ pipe search [-.include]libssh2.h libssh2_version_patch/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; - + define/job patchv &l ) +$! +$ majorv = f$trnlnm("majorv") +$ minorv = f$integer(f$trnlnm("minorv")) +$ patchv = f$integer( f$trnlnm("patchv")) +$! +$ OLBONLY = "FALSE" +$ if p1 .eqs. "OLBONLY" +$ then +$ OLBONLY = "TRUE" +$ endif +$! +$ deassign/job majorv +$ deassign/job minorv +$ deassign/job patchv +$! +$return +$! +$!--------------------------------------------------------------------- +$! +$Cleanup: subroutine +$! +$ set noon +$ purge *.opt +$ purge *.olb +$ purge *.exe +$! +$exit 1 +$endsubroutine +$! +$!--------------------------------------------------------------------- +$! +$LinkShared: subroutine +$! +$! +$! +$ cversion = f$fao("!3ZL",minorv) + f$fao("!3ZL",patchv) +$! +$! General linking options in link_libssh2_version...opt +$! Vectors in link_libssh2_vectors...opt +$! +$ open/write uitv link_libssh2_version_'majorv'_'minorv'_'patchv'.opt +$ write uitv "GSMATCH=LEQUAL,''majorv',''cversion'" +$ write uitv "IDENTIFICATION=""LIBSSH2 ''majorv'.''minorv'.''patchv'""" +$ write uitv "sys$share:ssl$libcrypto_shr32.exe/share" +$ write uitv "sys$share:ssl$libssl_shr32.exe/share" +$ write uitv "gnv$libzshr/share" +$ close uitv +$! +$ link/shared/exe=libssh2_'majorv'_'minorv'_'patchv'.exe - + libssh2.olb/lib, - + link_libssh2_version_'majorv'_'minorv'_'patchv'.opt/opt, - + link_libssh2_vectors_'majorv'_'minorv'_'patchv'.opt/opt +$! +$exit +$endsubroutine +$! +$!--------------------------------------------------------------------- +$! +$CompileAll: subroutine +$! +$ set noon +$! +$ if f$search("objdir:*.obj;*") .nes "" +$ then +$ delete objdir:*.obj;* +$ endif +$ if f$search("[.cxx_repository]cxx$demangler_db.;") .nes "" +$ then +$ delete [.cxx_repository]cxx$demangler_db.;* +$ endif +$! +$! Compile all .c files in [-.src], first as_is +$! and then as default all uppercase names +$! and add the resulting object to object libraries +$! libssh2_up.olb and libssh2_as_is.olb. +$! +$ case = 0 +$ if OLBONLY then case = 1 +$CaseLoop: +$! +$ if case .eq. 0 +$ then!camel case names +$ cc_flags = "/names=(shortened,as_is)''cc_define'" +$ objlib = "libssh2_asis.olb" +$ endif +$! +$ if case .eq. 1 +$ then!uppercase names +$ if f$search("[.cxx_repository]cxx$demangler_db.;") .nes "" +$ then +$ rename [.cxx_repository]cxx$demangler_db.; *.lowercase +$ purge [.cxx_repository]cxx$demangler_db.lowercase +$ endif +$! +$ cc_flags = "/names=(shortened)''cc_define'" +$ objlib = "libssh2_up.olb" +$ endif +$! +$ if f$search("''objlib';*") .nes. "" then delete 'objlib';* +$ library/create 'objlib' +$! +$Loop: +$ this = f$search("srcdir:*.c;0") +$ if this .eqs. "" then goto EndLoop +$! +$ what = f$parse( this,,,"name") +$! +$ call CompileAndAdd +$! +$ goto Loop +$EndLoop: +$ case = case + 1 +$ delete objdir:*.obj;* +$ if case .lt 2 then goto CaseLoop +$! +$ rename libssh2_up.olb libssh2.olb +$ if f$search("[.cxx_repository]cxx$demangler_db.;") .nes "" +$ then +$ rename [.cxx_repository]cxx$demangler_db.; *.uppercase +$ purge [.cxx_repository]cxx$demangler_db.uppercase +$ endif +$! +$ if OLBONLY then exit 4 +$! +$! For each function that is too long, create a global symbol +$! low$'shortened-uppercase-name' with as value lowercase shortened +$! name in it, so we can add the proper lower or mixed case +$! shortened name later when building the transfer vectors +$! for the shared image. +$! This is to prevent two very long similar function names +$! that are shortened getting mixed up when sorted alphabetically. +$! +$ inputfile = "[.cxx_repository]cxx$demangler_db.lowercase" +$ gosub GetShortened +$! +$ inputfile = "[.cxx_repository]cxx$demangler_db.uppercase" +$ gosub GetShortened +$! +$exit +$! +$GetShortened: +$! +$ open/read s 'inputfile' +$ namecount = 0 +$ReadLoop: +$! +$ read/end=endreadloop s regel +$! +$ shortname = f$element(0,"$",regel) + "$" +$ longname = f$element(1,"$",regel) +$! +$ symvalue = "" +$! +$ if shortname .eqs. f$edit(shortname,"upcase") +$ then +$! this is an uppercase shortname, add it +$ symname = "u$''longname'" +$ symvalue = "''shortname'" +$ low$'shortname' == l$'longname' +$! +$ delete/symbol l$'longname' +$! +$ else +$! this is an lowercase shortname +$ symname = "l$''longname'" +$ symvalue = "''shortname'" +$ 'symname' = "''symvalue'" +$ endif +$! +$ namecount = namecount + 1 +$! +$ goto ReadLoop +$EndReadLoop: +$! +$close s +$return +$! +$endsubroutine +$! +$!--------------------------------------------------------------------- +$! +$CompileAndAdd: subroutine +$! +$ on error then goto End +$! +$ cc /warn=disable=longextern/lis=objdir:/show=all 'cc_include' 'cc_flags'/object=objdir:'what'.obj srcdir:'what'.c +$ library/insert 'objlib' objdir:'what'.obj +$! +$End: +$exit +$endsubroutine +$! +$!--------------------------------------------------------------------- +$! +$BuildTransferVectors: subroutine +$! +$! Do a balanced read of the uppercase library names +$! and the mixed case library names, and build the +$! transfer vectors with uppercase entry points +$! with an alternative in mixed case. +$! For shortened names, use the low$* symbols +$! to avoid being fooled by the sort. +$! +$ thislib = "libssh2.olb" +$ library/lis=libu.'thisid'/names libssh2.olb +$ library/lis=lib_asisu.'thisid'/names libssh2_asis.olb +$! +$! case blind sort of all modules in both the uppercase +$! as the case sensitive object library. +$! +$ sort libu.'thisid' lib.'thisid'/spec=sys$input +/COLLATING_SEQUENCE=(SEQUENCE= ("A" - "Z","0"-"9","_"), FOLD) +$ sort lib_asisu.'thisid' lib_asis.'thisid'/spec=sys$input +/COLLATING_SEQUENCE=(SEQUENCE= ("A" - "Z","0"-"9","_"), FOLD) +$! +$ open/read in lib.'thisid' +$ open/read inasis lib_asis.'thisid' +$ open/write uit link_libssh2_vectors_'majorv'_'minorv'_'patchv'.opt +$! +$ write uit "CASE_SENSITIVE=YES" +$ write uit "SYMBOL_VECTOR= ( -" +$! +$ mode = 0 +$ uitregel = "" +$! +$ReadLoop: +$! +$ read/end=ReadAsis in regel +$ReadAsis: +$ read/end=EndReadLoop inasis asisregel +$! +$ regel = f$edit( regel, "trim,compress" ) +$ asisregel = f$edit( asisregel, "trim,compress" ) +$! +$ if f$element(0," ",regel) .eqs. "Module" .or. - + f$extract(0,1,regel) .eqs. "_" .or. - + f$element(1," ",regel) .nes. " " .or. - + regel .eqs. "" +$ then +$ goto ReadLoop +$ endif +$! +$ if uitregel .nes. "" .and. mode .eq. 1 +$ then +$ write uit "''uitregel'=PROCEDURE, -" +$ write uit "''uitasis'/''uitregel'=PROCEDURE, -" +$! +$ uitregel = "" +$ uitasis = "" +$ endif +$! +$ uitregel = regel +$ if f$type( low$'uitregel' ) .nes. "" +$ then +$ uitasis = low$'uitregel' +$ delete/symbol/global low$'uitregel' +$ else +$ uitasis = asisregel +$ endif +$! +$ mode = 1 +$! +$ goto ReadLoop +$EndreadLoop: +$! +$! To get the closing brace after the last procedure +$! keyword. +$! +$ if uitregel .nes. "" +$ then +$ write uit "''uitregel'=PROCEDURE, -" +$ write uit "''uitasis'/''uitregel'=PROCEDURE)" +$ endif +$! +$ write uit "CASE_SENSITIVE=NO" +$! +$ close in +$ close inasis +$ close uit +$! +$ delete lib*.'thisid';* +$! +$exit +$endsubroutine +$! +$!--------------------------------------------------------------------- +$! diff --git a/libssh2/vms/man2help.c b/libssh2/vms/man2help.c new file mode 100644 index 000000000..92e5f2b94 --- /dev/null +++ b/libssh2/vms/man2help.c @@ -0,0 +1,516 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +typedef struct manl{ + struct manl *next; + char *filename; +}man, *manPtr; + +typedef struct pf_fabnam{ + struct FAB dfab; + struct RAB drab; + struct namldef dnam; + char expanded_filename[NAM$C_MAXRSS + 1]; +} pfn, *pfnPtr; + +/*----------------------------------------------------------*/ + +fpcopy( char *output, char *input, int len ) +{ +char *is, *os; +int i; + +if ( len ){ + for ( is = input, os = output, i = 0; i < len ; ++i, ++is, ++os){ + *os = *is; + } + *os = 0; +}else{ + output[0] = 0; +} +} + + +/*----------------------------------------------------------*/ +/* give part of ilename in partname. See code for proper + value of i ( 0 = node, 1 = dev, 2 = dir,3 = name etc. +*/ + +int fnamepart( char *inputfile, char *part, int whatpart ) +{ +pfnPtr pf; +int status; +char ipart[6][256], *i, *p; + +pf = calloc( 1, sizeof( pfn ) ); + +pf->dfab = cc$rms_fab; +pf->drab = cc$rms_rab; +pf->dnam = cc$rms_naml; + +pf->dfab.fab$l_naml = &pf->dnam; + +pf->dfab.fab$l_fna = (char *) -1; +pf->dfab.fab$l_dna = (char *) -1; +pf->dfab.fab$b_fns = 0; +pf->dfab.fab$w_ifi = 0; + +pf->dnam.naml$l_long_defname = NULL; //inputfile; +pf->dnam.naml$l_long_defname_size = 0;//strlen( inputfile ); + +pf->dnam.naml$l_long_filename = inputfile; +pf->dnam.naml$l_long_filename_size = strlen( inputfile); + +pf->dnam.naml$l_long_expand = pf->expanded_filename; +pf->dnam.naml$l_long_expand_alloc = NAM$C_MAXRSS ; + +pf->dnam.naml$b_nop |= NAML$M_SYNCHK | NAML$M_PWD; + +status = sys$parse( &pf->dfab, 0,0); +if ( !(status&1) ){ + free( pf ); + return( status ); +} + +fpcopy ( ipart[0], pf->dnam.naml$l_long_node , pf->dnam.naml$l_long_node_size); +fpcopy ( ipart[1], pf->dnam.naml$l_long_dev , pf->dnam.naml$l_long_dev_size); +fpcopy ( ipart[2], pf->dnam.naml$l_long_dir , pf->dnam.naml$l_long_dir_size); +fpcopy ( ipart[3], pf->dnam.naml$l_long_name , pf->dnam.naml$l_long_name_size); +fpcopy ( ipart[4], pf->dnam.naml$l_long_type , pf->dnam.naml$l_long_type_size); +fpcopy ( ipart[5], pf->dnam.naml$l_long_ver , pf->dnam.naml$l_long_ver_size); + +for( i = ipart[ whatpart ], p = part; *i; ++i, ++p){ + if ( p == part ){ + *p = toupper( *i ); + }else{ + *p = tolower( *i ); + } +} +*p = 0; + +free( pf ); +return(1); +} +/*----------------------------------------------------------*/ + +int find_file(char *filename,char *gevonden,int *findex) +{ +int status; +struct dsc$descriptor gevondend; +struct dsc$descriptor filespec; +char gevonden_file[NAM$C_MAXRSS + 1]; + +filespec.dsc$w_length = strlen(filename); +filespec.dsc$b_dtype = DSC$K_DTYPE_T; +filespec.dsc$b_class = DSC$K_CLASS_S; +filespec.dsc$a_pointer = filename; + +gevondend.dsc$w_length = NAM$C_MAXRSS; +gevondend.dsc$b_dtype = DSC$K_DTYPE_T; +gevondend.dsc$b_class = DSC$K_CLASS_S; +gevondend.dsc$a_pointer = gevonden_file; + +status=lib$find_file(&filespec,&gevondend,findex,0,0,0,0); + +if ( (status & 1) == 1 ){ + strcpy(gevonden,strtok(gevonden_file," ")); +}else{ + gevonden[0] = 0; +} + +return(status); +} + + +/*--------------------------------------------*/ + +manPtr addman( manPtr *manroot,char *filename ) +{ +manPtr m,f; + +m = calloc( 1, sizeof( man) ); +if ( !m ) return( NULL ); + +m->filename = strdup( filename ); + +if ( *manroot == NULL ){ + *manroot = m; +}else{ + for( f = *manroot; f->next ; f = f->next ); + f->next = m; +} +return(m); +} + +/*--------------------------------------------*/ +void freeman( manPtr *manroot ) +{ +manPtr m,n; + +for( m = *manroot; m ; m = n ){ + free( m->filename ); + n = m->next; + free ( m ); +} +*manroot = NULL; +} + +/*--------------------------------------------*/ + +int listofmans( char *filespec, manPtr *manroot ) +{ +manPtr r; +int status; +int ffindex=0; +char gevonden[NAM$C_MAXRSS + 1]; + +while(1){ + status = find_file( filespec, gevonden, &ffindex ); + + if ( (status&1) ){ + r = addman( manroot, gevonden ); + if ( r == NULL ) return(2); + }else{ + if ( !( status&1)) break; + } +} + +lib$find_file_end( &ffindex); +if ( status == RMS$_NMF) status = 1; + + +return( status ); +} + +/*--------------------------------------------*/ + +int convertman ( char *filespec, FILE *hlp , int base_level, int add_parentheses ) +{ +FILE *man; +char *in, *uit; +char *m,*h; +size_t len, thislen, maxlen= 50000; +int bol,mode, return_status=1; +char subjectname[ NAM$C_MAXRSS + 1 ]; + +in = calloc( 1, maxlen + 1 ); +uit = calloc( 1, maxlen + 1 ); + +if ( in == NULL || uit == NULL ) return(2); + +man = fopen( filespec, "r"); +if ( man == NULL ) return(vaxc$errno); + +for( len = 0; !feof( man ) && len < maxlen ; len += thislen ){ + thislen = fread( in + len, 1, maxlen - len, man ); +} + +fclose (man); + +m = in; +h = uit; + +*(m + len ) = 0; + +for ( mode = 0, bol = 1 ; *m; ++m ){ + + switch ( mode ){ + case 0: + switch(*m){ + case '.': + if ( bol ){ + mode = 1; + }else{ + *h = *m; + ++h; + } + break; + case '\\': + if ( bol ){ + *h = ' ';++h; + *h = ' ';++h; + } + mode = 2; + break; + default: + if ( bol ){ + *h = ' ';++h; + *h = ' ';++h; + } + *h = *m; + ++h; + break; + } + break; + case 1: /* after . at bol */ + + switch(*m){ + case '\\': + while( *m != '\n' && *m != '\r' && *m )++m; + mode = 0; + break; + case 'B': + ++m; + *h = ' ';++h; + mode = 0; + break; + case 'I': + /* remove preceding eol */ + if ( *(m+1) != 'P' ){ + --h; + while ( (*h == '\n' || *h == '\r') && h > uit )--h; + ++h; + } + + /* skip .Ix */ + for(;*m != ' ' && *m != '\n' && *m != '\r'; ++m); + + /* copy line up to EOL */ + + for(;*m != '\n' && *m != '\r' && *m; ++m, ++h)*h = *m; + + /* if line ends in ., this is an EOL */ + + if ( *(h-1) == '.'){ + --h; + --m; + }else{ + /* if line does not end in ., skip EOL in source */ + + if ( *(m+1) == '\n' || *(m+1) == '\r')++m; + } + mode = 0; + break; + case 'S': + if ( *(m+1) == 'H' ){ + *h = '\n';++h; + if ( strncmp( m+3 ,"NAME",4) == 0 || + strncmp( m+3 ,"SYNOPSIS",8) == 0 || + strncmp( m+3 ,"DESCRIPTION",11) == 0 ){ + while( *m != '\n' && *m != '\r')++m; + mode = 0; + }else{ + ++m; + + /* write help level, and flag it */ + + *h = '0' + base_level + 1;++h; + return_status |= 2; + + *h = ' ';++h; + + /* skip H (or whatever after S) and blank */ + ++m;++m; + + for(;*m != '\n' && *m != '\r' && *m; ++m, ++h){ + + /* write help label in lowercase, skip quotes */ + /* fill blanks with underscores */ + + if ( *m != '\"' ){ + *h = tolower( *m ); + if (*h == ' ') *h = '_'; + }else{ + --h; + } + } + + /* Add a linefeed or two */ + + *h = *m;++h; + *h = *m;++h; + + mode = 0; + } + } + break; + case 'T': + if ( *(m+1) == 'H' ){ + *h = '0' + base_level; ++h; + return_status |= 2; + *h = ' ';++h; + for ( m = m + 3; *m != ' ' && *m ; ++m, ++h ){ + *h = *m; + } + if ( add_parentheses ){ + *h = '(';++h; + *h = ')';++h; + } + while( *m != '\n' && *m != '\r' && *m )++m; + mode = 0; + } + break; + default: + ++m; + mode = 0; + break; + } + break; + case 2: /* after \ skip two characters or print the backslash */ + switch(*m){ + case '\\': + *h = *m; + ++h; + mode = 0; + break; + default: + ++m; + mode = 0; + break; + } + break; + } /*end switch mode */ + + bol = 0; + if ( *m == '\n' || *m == '\r') bol = 1; + +}/* end for mode */ + +*h = 0; + + +if ( (return_status&2) ){ + fprintf( hlp, "%s\n\n", uit); +}else{ + fnamepart( filespec, subjectname,3); + if ( *subjectname ){ + fprintf( hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit); + }else{ + /* No filename (as is the case with a logical), use first word as subject name */ + char *n,*s; + + for(n = in; isspace( *n );++n); + for(s = subjectname; !(isspace( *n )); ++n,++s)*s = *n; + *s = 0; + + fprintf( hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit); + } +} + +/* + printf( "read %d from %s, written %d to helpfile, return_status = %d\n", + len, filespec, strlen(uit), return_status ); +*/ + +free( m ); +free( h ); + +return ( 1); +} + +/*--------------------------------------------*/ + +int convertmans( char *filespec, char *hlpfilename, int base_level, int append, int add_parentheses ) +{ +int status=1; +manPtr manroot=NULL, m; +FILE *hlp; + +if ( append ){ + hlp = fopen( hlpfilename,"a+"); +}else{ + hlp = fopen( hlpfilename,"w"); +} + +if ( hlp == NULL ) return( vaxc$errno ); + +status = listofmans( filespec, &manroot ); +if ( !(status&1) ) return( status ); + +for ( m = manroot ; m ; m = m->next ){ + status = convertman( m->filename, hlp , base_level, add_parentheses ); + if ( !(status&1) ){ + fprintf(stderr,"Convertman of %s went wrong\n", m->filename); + break; + } +} +freeman( &manroot ); +return( status ); +} + +/*--------------------------------------------*/ +void print_help() +{ + fprintf( stderr, "Usage: [-a] [-b x] convertman \n" ); + fprintf( stderr, " -a append to \n" ); + fprintf( stderr, " -b if no headers found create one with level \n" ); + fprintf( stderr, " and the filename as title.\n" ); + fprintf( stderr, " -p add parentheses() to baselevel help items.\n" ); + +} +/*--------------------------------------------*/ + +main ( int argc, char **argv ) +{ +int status; +int i,j; +int append, base_level, basechange, add_parentheses; +char *manfile=NULL; +char *helpfile=NULL; + +if ( argc < 3 ){ + print_help(); + return( 1 ) ; +} + +append = 0; +base_level = 1; +basechange = 0; +add_parentheses = 0; + +for ( i = 1; i < argc; ++i){ + if ( argv[i][0] == '-' ){ + for( j = 1; argv[i][j] ; ++j ){ + switch( argv[i][j] ){ + case 'a': + append = 1; + break; + case 'b': + if ( (i+1) < argc ){ + base_level = atoi( argv[ i + 1 ] ); + basechange = 1; + } + break; + case 'p': + add_parentheses = 1; + break; + } + } + if ( basechange){ + basechange = 0; + i = i + 1; + } + }else{ + if ( manfile == NULL ){ + manfile = strdup( argv[i]); + } else if ( helpfile == NULL ){ + helpfile = strdup( argv[i]); + } else { + fprintf( stderr, "Unrecognized parameter : %s\n", argv[i]); + } + } +} + + +/* fprintf( stderr,"manfile: %s, helpfile: %s, append: %d, base_level : %d\n", + manfile, helpfile, append, base_level); +*/ + +status = convertmans( manfile, helpfile, base_level, append, add_parentheses ); + +free( manfile ); +free( helpfile ); + +return( status ); +} + + diff --git a/libssh2/vms/readme.vms b/libssh2/vms/readme.vms new file mode 100644 index 000000000..978da1974 --- /dev/null +++ b/libssh2/vms/readme.vms @@ -0,0 +1,319 @@ +*These are the porting notes to OpenVMS, as of 7 April 2010 +by Jose Baars. This file will be installed as +libssh2*.release_notes by the product install kit. + + +LIBSSH2 +------- + +LIBSSH2 is a client-side library written in C that aims to +implement the SSH2 protocol. It is an open source project, +to be found at https://libssh2.org. + +GNV +--- + +The library uses the GNV prefix, on advise of the kind supporter +of the GNV project, John Malmberg. + +Installing the PCSI kit +======================= + +Prerequisites +------------- +- VMS version 8.3 minimal. + See the remarks at prerequisites for building the kit +- TCP/IP stack, both TCP/IP services and Multinet should work. + See the remarks at prerequisites for building the kit +- HP OPENSSL V1.3 minimal. + See the remarks at prerequisites for building the kit +- JEM ZLIB V1.2-3E1 minimal. + See the remarks at prerequisites for building the kit + +The first three dependencies are tested at installation time, and +installation will fail if any these products are not installed. +The ZLIB dependency is not tested by the product installation +procedure, as libssh2 will probably be installed as part of +multiple libraries including zlib. + +Install +------- + + +The kit will install gnv$libssh2.exe in a directory tree that might +already be available on your system if you have installed other gnv* +libraries or utilities. + +The directory tree for gnv$libssh2.exe will be like this: + +[gnv] -- [usr] -- [include] -- [libssh2] include files for libssh2 + [lib] gnv$libssh2_x_y_z.exe + [share] -- [doc] -- [libssh2] libssh2.hlb, + release notes (this file), + libssh2 release notes + +optional: + [example] libssh2_examples-x_y_z.bck + [common_src] libssh2-x_y_z_src.bck + +By default, it will install the shared image and include files to +SYS$COMMON:[GNV...]. + +You can override this destination by specifying the destination +directory after /DESTINATION= on the product install command line. +This is particularly of use when installing the library on a cluster +without a common system disk. + +Please ignore the following warnings, as the kit is not signed : + +%PCSI-I-CANNOTVAL, cannot validate dev:[dir]JCB-AXPVMS-LIBSSH2-V0102-05D20100402-1.PCSI +-PCSI-I-NOTSIGNED, product kit is not signed and therefore has no manifest file + +Optionally, you can install a backup saveset with some programming examples, +or a backupo saveset with the complete libssh2 source tree. + +you will need to answer 'NO' to the question +'Do you want the default for all options'. + +and 'YES' to either or both the following questions: + + Do you want the libssh2 C programming examples ? [NO] + + Do you want the complete libssh2 source tree ? [NO] + + +Post installation tasks +----------------------- + +Although we will try to maintain upward compatibility of libssh2, +this can not be guaranteed by the libssh2 project itself for OpenVMS, +nor eternally by us. + +To use libssh2 effectively, you will have to define a system logical +to point to the shared image. If you are willing to take the gamble, +define this logical in your systartup like so: + +$ define/system/executive gnv$libssh2 dev:[dir..]gnv$libssh2_x_y_z.exe + +Optionally, you can install the executbale like so: + +$ mc sysgen install dev:[dir..]gnv$libssh2_x_y_z.exe/open/share/header + +Link your programs against gnv$libssh2, and when upgrading libssh2 +test thoroughly. + +If you want to be extra cautious define a system logical like this: + +$ define/system/executive gnv$libssh2_x_y_z dev:[dir..]gnv$libssh2_x_y_z.exe + +Link programs against gnv$libssh2_x_y_z, and when upgrading libssh2 +link against new versions. + +It is probably more convenient in the last case to link against the object +library provided in the source backup saveset. Both an uppercase and a +mixed case object library, called libssh2.olb and libssh2_asis.olb +are provided. + + +Compiling and linking against libssh2 +------------------------------------- + +The shared image library has a vector table with both uppercase and +mixed case entry points, allowing to link directly against the shared +image wether you need the /NAMES=AS_IS or not. + +To link successfully, you MUST use /NAMES=shortened, as some function +names in libssh2 are longer than the VMS maximum of 32 characters. + +If you chose to install the examples, you can unpack the backup +saveset by + +backup/sel=*.c device:[gnv.usr.share.doc.libssh2.examples]libssh2_examples-x_y_z.bck - + [] + +They can by compiled and linked by these commands ( provided you have defined +the gnv$libssh2 logical) : + +$ cc/include=dev:[gnv.usr.include.libssh2] xxx.c/names=shortened +$ link/opt=sys$input: xxx.obj +gnv$libssh2/share + + + + +Building gnv$libssh2 +==================== + +You can build gnv$libssh2 yourself, which may have advantages, as the library is +in full development, very regularly new features are added. + +For production use, it is probably advisable to use a stable version, and +link against that. To check out new features, statically linking against +the object library is probably more practical, to avoid compatibility +issues. + + +Prerequisites +------------- + +You will need to have the following available: + +- An Alpha or Itanium VMS system. Due to dependencies on zlib, ssl and ODS-5, + support on VAXen would be cumbersome at least. + +- VMS version 8.3 minimal. This is a requirement of gnv$zlibshr.exe against + which shared image library libssh2 is linked. If you use another zlib + to link against, you can make it work under lower versions of VMS. + I have made it work on VMS 7.3-2 with not a lot of difficulty. + Also, if you are not interested in compression, you can choose not + to link against zlib at all; in that case comment out the + #define LIBSSH2_HAVE_ZLIB in libssh2_config.h. + +- TCP/IP services or Multinet for OpenVMS. + TCPWare has not been tested. + +- The HP OpenSSL product. Of course, with tweaking, you can probably link + it against the OpenSSL library, but that is not what I have used. + +- A C compiler. I don't know any other working C compilers than + the DEC/Compac/HP-C compiler on VMS. + +- An ODS-5 disk. With tweaking you'll get it to work on an ODS-2 + disk, but it is unpractical to do so. + +- A version of VMSTAR that understands ODS-5 disks and extended + filenames. Look here: + http://ftp.process.com/ftp/vms-freeware/fileserv/vmstar.zip + +- gunzip, available for instance at Steven M Schweda's website: + http://antinode.info/ftp/gzip/gzip-1_3_12b_vms/gzip-1_3_12b_vms.zip + +Optional: + +- curl, to be found at https://curl.haxx.se + You might want to use curl to download the libssh2 kit directly + to you VMS machine. Interestingly, sftp in curl is implemented using + libssh2, soon to be expected on VMS as well, hopefully. + +Downloading libssh2 +------------------- + +At the website of libssh2, you can find stable and daily gzipped +tarballs. if you have a computer connected to internet you can +download a daily build yourself by a procedure that looks a lot like +this ( fill out your own proxy user/password, set up right symbols to +gunzip, vmstar and curl and set up the libssh2 build version): + +$ libssh2_version = "1.2.6" +$! +$ proxy_line = " ""-U"" ""''proxy_userpass'"" ""-x"" ""''proxy_hostport'"" " +$! +$ currentday = f$cvtime(,,"date") - "-" - "-" +$! +$ set def mydev:[mydir.libssh2] +$! +$ if f$search("libssh2-''libssh2_version'-''currentday'.tar.gz") .nes. "" +$ then +$ delete libssh2-'libssh2_version'-'currentday'.tar.gz;* +$ endif +$! +$ curl 'proxy_line' "https://libssh2.org/snapshots/libssh2-''libssh2_version'-''currentday'.tar.gz" - + -o libssh2-'libssh2_version'-'currentday'.tar.gz +$! +$! +$ if f$search("libssh2-''libssh2_version'-''currentday'.tar.;") .nes. "" +$ then +$ delete libssh2-'libssh2_version'-'currentday'.tar.;* +$ endif +$! +$ gunzip libssh2-'libssh2_version'-'currentday'.tar.gz +$! +$ tarfile = f$search("libssh2-''libssh2_version'-''currentday'.tar.;") +$ vmstar xf 'tarfile' + +Downloading a stable build will need you to get rid of the currentday. + +After the download, you should have a directory tree with a toplevel +directory called [libssh2-x.y.z-yyyymmdd]. +One of the subdirectories is called vms. + +Getting the libssh2 sources from the source backup in the binary kit +-------------------------------------------------------------------- + +During installation of the binary kit, you are given the option +of installing the sources. If chosen, a backup saveset with +the complete libssh2 directory is made available in +[gnv.common_src]. + +By restoring this backup saveset, you end up with the same +set of files as by the direct download from libssh2.org. + + +Building the library +-------------------- + +To avoid all kinds of misunderstandings caused by firewalls thinking that +a .com file must be an MS-DOS executable, all command procedures are called +.dcl. + +Go to the vms subdirectory in the download tree, and issue the following +command: + +@libssh2_make_lib.dcl + +This should produce libssh2_x_y_z.exe in this same vms directory. + + + +Building the examples +--------------------- + +A number of examples are also part of the full libssh2 delivery. +You can compile and link them either against the object library +produced when building the shared image, or against the shared image +produced in the step before. + +You can compile only one of the examples by giving only the +name part of the filename of the example as p1 to the +build procedure: + +@libssh2_make_example.dcl + +or for instance + +@libssh2_make_example.dcl sftp + +By default, libssh2_make_example.dcl links to the object libraries +produced by the libssh2_make_lib.dcl procedure. If you want to link +against the shared image library made in the same procedure, invoke +the procedure like so: + +@libssh2_make_example.dcl sftp "SHARED" + +The procdure defines a process logical gnv$libssh2 pointing to the shared +image library in the directory, which obviously will not survive a logout. + + +Building the help library +------------------------- + +The man pages can be converted to a VMS help library by issuing +this command : + +@libssh2_make_help.dcl + +It uses a simple but fairly effective c program man2help.c +to achieve this. + +Building a PCSI kit +------------------- + +When you have built the shared library and the help library, +you can build a PCSI kit by issueing this command: + +@libssh2_make_kit.dcl + + + + + diff --git a/libssh2/win32/GNUmakefile b/libssh2/win32/GNUmakefile new file mode 100644 index 000000000..86857513c --- /dev/null +++ b/libssh2/win32/GNUmakefile @@ -0,0 +1,350 @@ +######################################################################### +# +## Makefile for building libssh2 (Win32 version - gnu make) +## Use: make -f GNUmakefile [help|all|clean|dev|devclean|dist|distclean|dll|objclean] +## +## Hacked by: Guenter Knauf +# +######################################################################### + +# Edit the path below to point to the base of your Zlib sources. +ifndef ZLIB_PATH +ZLIB_PATH = ../../zlib-1.2.8 +endif + +# Edit the path below to point to the base of your OpenSSL package. +ifndef OPENSSL_PATH +OPENSSL_PATH = ../../openssl-1.0.2d +endif + +# Edit the path below to point to your Distribution folder. +ifndef DISTDIR +DISTDIR = libssh2-$(LIBSSH2_VERSION_STR)-bin-$(ARCH) +endif +DISTARC = $(DISTDIR).zip + +# Edit the path below to point to your Development folder. +ifndef DEVLDIR +DEVLDIR = libssh2-$(LIBSSH2_VERSION_STR)-dev-$(ARCH) +endif +DEVLARC = $(DEVLDIR).zip + +# Project root +PROOT = .. + +# Edit the vars below to change target settings. +TARGET = libssh2 +WWWURL = https://www.libssh2.org/ +DESCR = libssh2 $(LIBSSH2_VERSION_STR) +#STACK = 64000 + +# must be equal to DEBUG or NDEBUG +ifndef DB + DB = NDEBUG + # DB = DEBUG +endif +# Optimization: -O or debugging: -g +ifeq ($(DB),NDEBUG) + OPT = -O2 + OBJDIR = release +else + OPT = -g + OPT += -DLIBSSH2DEBUG + OBJDIR = debug +endif + +# Here you can find a native Win32 binary of the original awk: +# http://www.gknw.net/development/prgtools/awk-20100523.zip +AWK = awk +ZIP = zip -qzr9 + +# Platform-dependent helper tool macros +ifeq ($(findstring /sh,$(SHELL)),/sh) +DEL = rm -f $1 +RMDIR = rm -fr $1 +MKDIR = mkdir -p $1 +COPY = -cp -afv $1 $2 +#COPYR = -cp -afr $1/* $2 +COPYR = -rsync -aC $1/* $2 +TOUCH = touch $1 +CAT = cat +ECHONL = echo "" +DL = ' +else +ifeq "$(OS)" "Windows_NT" +DEL = -del 2>NUL /q /f $(subst /,\,$1) +RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) +else +DEL = -del 2>NUL $(subst /,\,$1) +RMDIR = -deltree 2>NUL /y $(subst /,\,$1) +endif +MKDIR = -md 2>NUL $(subst /,\,$1) +COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) +COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2) +TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,, +CAT = type +ECHONL = $(ComSpec) /c echo. +endif + +# The following line defines your compiler. +ifdef METROWERKS + CC = mwcc +else + CC = $(CROSSPREFIX)gcc +endif + +# Set environment var ARCH to your architecture to override autodetection. +ifndef ARCH +ifeq ($(findstring gcc,$(CC)),gcc) +ifeq ($(findstring x86_64,$(shell $(CC) -dumpmachine)),x86_64) +ARCH = w64 +else +ARCH = w32 +endif +else +ARCH = w32 +endif +endif + +# Include the version info retrieved from libssh2.h +-include $(OBJDIR)/version.inc + +# Global flags for all compilers +CFLAGS = $(LIBSSH2_CFLAG_EXTRAS) $(OPT) -D$(DB) -DLIBSSH2_WIN32 # -DHAVE_CONFIG_H +LDFLAGS = $(LIBSSH2_LDFLAG_EXTRAS) + +ifeq ($(CC),mwcc) +LD = mwld +RC = mwwinrc +LDFLAGS += -nostdlib +AR = $(LD) +ARFLAGS = -nostdlib -library -o +LIBEXT = lib +#RANLIB = +LIBPATH += -lr "$(METROWERKS)/MSL" -lr "$(METROWERKS)/Win32-x86 Support" +LDLIBS += -lMSL_Runtime_x86.lib -lMSL_C_x86.lib -lMSL_Extras_x86.lib +RCFLAGS = +CFLAGS += -nostdinc -gccinc -msgstyle gcc -inline off -opt nointrinsics -proc 586 +CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support" +CFLAGS += -w on,nounused,nounusedexpr # -ansi strict +else +LD = $(CROSSPREFIX)gcc +RC = $(CROSSPREFIX)windres +LDFLAGS += -s -shared -Wl,--output-def,$(TARGET).def,--out-implib,$(TARGET)dll.a +AR = $(CROSSPREFIX)ar +ARFLAGS = -cq +LIBEXT = a +RANLIB = $(CROSSPREFIX)ranlib +RCFLAGS = -I $(PROOT)/include -O coff +CFLAGS += -fno-builtin +CFLAGS += -fno-strict-aliasing +CFLAGS += -Wall # -pedantic +ifeq ($(ARCH),w64) +CFLAGS += -m64 -D_AMD64_ +LDFLAGS += -m64 +RCFLAGS += -F pe-x86-64 +else +CFLAGS += -m32 +LDFLAGS += -m32 +RCFLAGS += -F pe-i386 +endif +endif + +INCLUDES = -I$(PROOT)/win32 -I$(PROOT)/include + +ifdef WITH_WINCNG +CFLAGS += -DLIBSSH2_WINCNG +LDLIBS += -lbcrypt -lcrypt32 +else +CFLAGS += -DLIBSSH2_OPENSSL +ifndef OPENSSL_INCLUDE + ifeq "$(wildcard $(OPENSSL_PATH)/outinc)" "$(OPENSSL_PATH)/outinc" + OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc + endif + ifeq "$(wildcard $(OPENSSL_PATH)/include)" "$(OPENSSL_PATH)/include" + OPENSSL_INCLUDE = $(OPENSSL_PATH)/include + endif +endif +ifneq "$(wildcard $(OPENSSL_INCLUDE)/openssl/opensslv.h)" "$(OPENSSL_INCLUDE)/openssl/opensslv.h" +$(error Invalid OPENSSL_PATH: $(OPENSSL_PATH)) +endif +INCLUDES += -I"$(OPENSSL_INCLUDE)" +ifndef OPENSSL_LIBPATH + OPENSSL_LIBS_STAT = crypto ssl + ifeq "$(wildcard $(OPENSSL_PATH)/out)" "$(OPENSSL_PATH)/out" + OPENSSL_LIBPATH = $(OPENSSL_PATH)/out + OPENSSL_LIBS_DYN = eay32 ssl32 + endif + ifeq "$(wildcard $(OPENSSL_PATH)/lib)" "$(OPENSSL_PATH)/lib" + OPENSSL_LIBPATH = $(OPENSSL_PATH)/lib + OPENSSL_LIBS_DYN = crypto.dll ssl.dll + endif +endif +ifdef LINK_OPENSSL_STATIC + LDLIBS += $(patsubst %,$(OPENSSL_LIBPATH)/lib%.$(LIBEXT), $(OPENSSL_LIBS_STAT)) -lgdi32 +else + LDLIBS += $(patsubst %,$(OPENSSL_LIBPATH)/lib%.$(LIBEXT), $(OPENSSL_LIBS_DYN)) +endif +endif +ifeq ($(CC),mwcc) +LDLIBS += -lkernel32.lib -luser32.lib -lwsock32.lib +else +#LDLIBS += -lwsock32 +LDLIBS += -lws2_32 +endif + +ifdef WITH_ZLIB + CFLAGS += -DLIBSSH2_HAVE_ZLIB + INCLUDES += -I$(ZLIB_PATH) + ifdef LINK_ZLIB_STATIC + LDLIBS += $(ZLIB_PATH)/libz.$(LIBEXT) + else + LDLIBS += $(ZLIB_PATH)/libz.dll.$(LIBEXT) + endif +endif + +CFLAGS += $(INCLUDES) + +vpath %.c $(PROOT)/src + +ifdef WITH_WINCNG +include $(PROOT)/Makefile.WinCNG.inc +else +include $(PROOT)/Makefile.OpenSSL.inc +endif + +# include Makefile.inc to get CSOURCES define +include $(PROOT)/Makefile.inc + +OBJECTS := $(patsubst %.c,%.o,$(CSOURCES)) +OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS)) +OBJL = $(OBJS) $(OBJDIR)/$(TARGET).res + + +all: lib dll + +dll: prebuild $(TARGET).dll + +lib: prebuild $(TARGET).$(LIBEXT) + +prebuild: $(OBJDIR) $(OBJDIR)/version.inc +# libssh2_config.h + +test: all + $(MAKE) -C test -f GNUmakefile + +$(OBJDIR)/%.o: %.c +# @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)/version.inc: $(PROOT)/get_ver.awk $(PROOT)/include/libssh2.h $(OBJDIR) + @echo Creating $@ + @$(AWK) -f $^ > $@ + +dist: all $(DISTDIR) $(DISTDIR)/readme.txt + @$(call MKDIR, $(DISTDIR)/bin) + @$(call COPY, $(PROOT)/AUTHORS, $(DISTDIR)) + @$(call COPY, $(PROOT)/COPYING, $(DISTDIR)) + @$(call COPY, $(PROOT)/INSTALL, $(DISTDIR)) + @$(call COPY, $(PROOT)/README, $(DISTDIR)) + @$(call COPY, $(PROOT)/RELEASE-NOTES, $(DISTDIR)) + @$(call COPY, $(TARGET).dll, $(DISTDIR)/bin) + @echo Creating $(DISTARC) + @$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt + +dev: all $(DEVLDIR) $(DEVLDIR)/readme.txt + @$(call MKDIR, $(DEVLDIR)/bin) + @$(call MKDIR, $(DEVLDIR)/include) + @$(call MKDIR, $(DEVLDIR)/win32) + @$(call COPY, $(PROOT)/AUTHORS, $(DEVLDIR)) + @$(call COPY, $(PROOT)/COPYING, $(DEVLDIR)) + @$(call COPY, $(PROOT)/INSTALL, $(DEVLDIR)) + @$(call COPY, $(PROOT)/README, $(DEVLDIR)) + @$(call COPY, $(PROOT)/RELEASE-NOTES, $(DEVLDIR)) + @$(call COPY, $(TARGET).dll, $(DEVLDIR)/bin) + @$(call COPY, $(PROOT)/include/*.h, $(DEVLDIR)/include) + @$(call COPY, libssh2_config.h, $(DEVLDIR)/include) + @$(call COPY, *.$(LIBEXT), $(DEVLDIR)/win32) + @echo Creating $(DEVLARC) + @$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt + +distclean vclean: clean + $(call RMDIR, $(DISTDIR)) + $(call DEL, $(DISTARC)) + +devclean: clean + $(call RMDIR, $(DEVLDIR)) + $(call DEL, $(DEVLARC)) + +objclean: all + $(call RMDIR, $(OBJDIR)) + +testclean: clean + $(MAKE) -C test -f GNUmakefile clean + +clean: +# $(call DEL, libssh2_config.h) + $(call DEL, $(TARGET).dll $(TARGET).def $(TARGET).$(LIBEXT) $(TARGET)dll.$(LIBEXT)) + $(call RMDIR, $(OBJDIR)) + +$(OBJDIR): + @$(call MKDIR, $@) + +$(DISTDIR): + @$(call MKDIR, $@) + +$(DEVLDIR): + @$(call MKDIR, $@) + +$(TARGET).$(LIBEXT): $(OBJS) + @echo Creating $@ + @$(call DEL, $@) + @$(AR) $(ARFLAGS) $@ $^ +ifdef RANLIB + @$(RANLIB) $@ +endif + +$(TARGET).dll $(TARGET)dll.a: $(OBJL) + @echo Linking $@ + @$(call DEL, $@) + @$(LD) $(LDFLAGS) $^ -o $@ $(LIBPATH) $(LDLIBS) + + +$(OBJDIR)/%.res: %.rc + @echo Creating $@ + @$(RC) $(RCFLAGS) -i $< -o $@ + + +$(DISTDIR)/readme.txt: GNUmakefile + @echo Creating $@ + @echo $(DL)This is a binary distribution for Win32 platform.$(DL) > $@ + @echo $(DL)libssh version $(LIBSSH2_VERSION_STR)$(DL) >> $@ + @echo $(DL)Please download the complete libssh package for$(DL) >> $@ + @echo $(DL)any further documentation:$(DL) >> $@ + @echo $(DL)$(WWWURL)$(DL) >> $@ + +$(DEVLDIR)/readme.txt: GNUmakefile + @echo Creating $@ + @echo $(DL)This is a development distribution for Win32 platform.$(DL) > $@ + @echo $(DL)libssh version $(LIBSSH2_VERSION_STR)$(DL) >> $@ + @echo $(DL)Please download the complete libssh package for$(DL) >> $@ + @echo $(DL)any further documentation:$(DL) >> $@ + @echo $(DL)$(WWWURL)$(DL) >> $@ + +help: $(OBJDIR)/version.inc + @echo $(DL)===========================================================$(DL) + @echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL) + @echo $(DL)Zlib path = $(ZLIB_PATH)$(DL) + @echo $(DL)===========================================================$(DL) + @echo $(DL)libssh $(LIBSSH2_VERSION_STR) - available targets are:$(DL) + @echo $(DL)$(MAKE) all$(DL) + @echo $(DL)$(MAKE) dll$(DL) + @echo $(DL)$(MAKE) lib$(DL) + @echo $(DL)$(MAKE) clean$(DL) + @echo $(DL)$(MAKE) dev$(DL) + @echo $(DL)$(MAKE) devclean$(DL) + @echo $(DL)$(MAKE) dist$(DL) + @echo $(DL)$(MAKE) distclean$(DL) + @echo $(DL)$(MAKE) objclean$(DL) + @echo $(DL)$(MAKE) test$(DL) + @echo $(DL)===========================================================$(DL) diff --git a/libssh2/win32/Makefile.Watcom b/libssh2/win32/Makefile.Watcom new file mode 100644 index 000000000..1e8cede62 --- /dev/null +++ b/libssh2/win32/Makefile.Watcom @@ -0,0 +1,190 @@ +# +# Watcom / OpenWatcom Win32 makefile for libssh2. +# +# Comments to: Guenter Knauf http://www.gknw.net/phpbb +# + +!ifndef %watcom +!error WATCOM environment variable not set! +!else +SYS_INCL = -I$(%watcom)\h\nt -I$(%watcom)\h +SYS_LIBS = $(%watcom)\lib386\nt;$(%watcom)\lib386 +!endif + +!ifdef %libname +LIBNAME = $(%libname) +!else +LIBNAME = libssh2 +!endif +TARGETS = $(LIBNAME).dll $(LIBNAME)_imp.lib $(LIBNAME).lib + +CC = wcc386 +LD = wlink +AR = wlib +RC = wrc + +!ifdef __LOADDLL__ +! loaddll wcc386 wccd386 +! loaddll wpp386 wppd386 +! loaddll wlib wlibd +! if $(__VERSION__) > 1270 +! loaddll wlink wlinkd +! else +! loaddll wlink wlink +! endif +!endif + +!if $(__VERSION__) < 1250 +RM = del /q /f 2>NUL +!else +RM = rm -f +!endif +MD = mkdir +RD = rmdir /q /s 2>NUL +CP = copy + +CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -zc -s -fr=nul -w2 -fpi -oilrtfm & + -wcd=201 -bt=nt -d+ -dWIN32 -DLIBSSH2_WIN32 & + -I. -I..\include $(SYS_INCL) + +!ifdef %debug +DEBUG = -dDEBUG=1 -dDEBUGBUILD +CFLAGS += -d3 $(DEBUG) +!else +CFLAGS += -d0 +!endif + +!ifdef %use_ipv6 +CFLAGS += -d_WIN32_WINNT=0x0501 -dENABLE_IPV6 +!endif + +# +# Change to suite. +# +!ifdef %zlib_root +ZLIB_ROOT = $(%zlib_root) +!else +ZLIB_ROOT = ..\..\zlib-1.2.8 +!endif + +!ifdef %openssl_root +OPENSSL_ROOT = $(%openssl_root) +!else +OPENSSL_ROOT = ..\..\openssl-0.9.8zc +!endif + +!ifdef %use_zlib +CFLAGS += -DLIBSSH2_HAVE_ZLIB -I$(ZLIB_ROOT) +!endif + +!ifdef %use_wincng +CFLAGS += -DLIBSSH2_WINCNG +!else +CFLAGS += -wcd=138 -dLIBSSH2_OPENSSL -I$(OPENSSL_ROOT)\inc32 +!endif + +!ifdef %use_watt32 +CFLAGS += -dUSE_WATT32 -I$(%watt_root)\inc +!endif + +OBJ_BASE = WC_Win32.obj +LINK_ARG = $(OBJ_BASE)\dyn\wlink.arg +LIB_ARG = $(OBJ_BASE)\stat\wlib.arg + +# In order to process Makefile.inc wmake must be called with -u switch! +!ifndef %MAKEFLAGS +!error You MUST call wmake with the -u switch! +!else +!ifdef %use_wincng +!include ..\Makefile.WinCNG.inc +!else +!include ..\Makefile.OpenSSL.inc +!endif +!include ..\Makefile.inc +!endif + +OBJS = $(CSOURCES:.c=.obj) +OBJS = $OBJ_DIR\$(OBJS: = $OBJ_DIR\) + +# +# Use $(OBJS) as a template to generate $(OBJS_STAT) and $(OBJS_DYN). +# +OBJ_DIR = $(OBJ_BASE)\stat +OBJS_STAT = $+ $(OBJS) $- + +OBJ_DIR = $(OBJ_BASE)\dyn +OBJS_DYN = $+ $(OBJS) $- + +RESOURCE = $(OBJ_BASE)\dyn\libssh2.res + +.c: ..\src + + +all: $(OBJ_BASE) $(TARGETS) .SYMBOLIC + @echo Welcome to libssh2 + +clean: .SYMBOLIC + -$(RM) $(OBJS_STAT) + -$(RM) $(OBJS_DYN) + -$(RM) $(RESOURCE) $(LINK_ARG) $(LIB_ARG) + +vclean realclean: clean .SYMBOLIC + -$(RM) $(TARGETS) $(LIBNAME).map $(LIBNAME).sym + -$(RD) $(OBJ_BASE)\stat + -$(RD) $(OBJ_BASE)\dyn + -$(RD) $(OBJ_BASE) + +$(OBJ_BASE): + -$(MD) $^@ + -$(MD) $^@\stat + -$(MD) $^@\dyn + +$(LIBNAME).dll: $(OBJS_DYN) $(RESOURCE) $(LINK_ARG) + $(LD) name $^@ @$]@ + +$(LIBNAME).lib: $(OBJS_STAT) $(LIB_ARG) + $(AR) -q -b -c $^@ @$]@ + +.ERASE +$(RESOURCE): libssh2.rc + $(RC) $(DEBUG) -q -r -zm -I..\include $(SYS_INCL) $[@ -fo=$^@ + +.ERASE +.c{$(OBJ_BASE)\dyn}.obj: + $(CC) $(CFLAGS) -bd -br $[@ -fo=$^@ + +.ERASE +.c{$(OBJ_BASE)\stat}.obj: + $(CC) $(CFLAGS) $[@ -fo=$^@ + +$(LINK_ARG): $(__MAKEFILES__) + %create $^@ + @%append $^@ system nt dll + @%append $^@ file { $(OBJS_DYN) } +!ifdef %debug + @%append $^@ debug all + @%append $^@ option symfile +!endif + @%append $^@ option quiet, map, caseexact, eliminate, implib=$(LIBNAME)_imp.lib, + @%append $^@ res=$(RESOURCE) libpath $(SYS_LIBS) +!ifdef %use_watt32 + @%append $^@ library $(%watt_root)\lib\wattcpw_imp.lib +!else + @%append $^@ library ws2_32.lib +!endif +!ifdef %use_zlib + @%append $^@ library '$(ZLIB_ROOT)\zlib.lib' +!endif +!ifdef %use_wincng + @%append $^@ library bcrypt.lib + @%append $^@ library crypt32.lib +!else + @%append $^@ library '$(OPENSSL_ROOT)\out32\libeay32.lib' + @%append $^@ library '$(OPENSSL_ROOT)\out32\ssleay32.lib' +!endif + +$(LIB_ARG): $(__MAKEFILES__) + %create $^@ + @for %f in ($(OBJS_STAT)) do @%append $^@ +- %f + + diff --git a/libssh2/win32/config.mk b/libssh2/win32/config.mk new file mode 100644 index 000000000..21fe2e551 --- /dev/null +++ b/libssh2/win32/config.mk @@ -0,0 +1,54 @@ + +# Tweak these for your system +!if "$(OPENSSLINC)" == "" +OPENSSLINC=..\openssl-0.9.8zc\inc32 +!endif + +!if "$(OPENSSLLIB)" == "" +OPENSSLLIB=..\openssl-0.9.8zc\out32dll +!endif + +!if "$(ZLIBINC)" == "" +ZLIBINC=..\zlib-1.2.8 +!endif + +!if "$(ZLIBLIB)" == "" +ZLIBLIB=..\zlib-1.2.8 +!endif + +!if "$(TARGET)" == "" +TARGET=Release +!endif + +!if "$(TARGET)" == "Debug" +SUFFIX=_debug +CPPFLAGS=/Od /MDd +DLLFLAGS=/DEBUG /LDd +!else +CPPFLAGS=/Oi /O2 /Oy /GF /Y- /MD /DNDEBUG +DLLFLAGS=/DEBUG /LD +!endif + +CPPFLAGS=/nologo /GL /Zi /EHsc $(CPPFLAGS) /Iwin32 /Iinclude + +!if "$(WITH_WINCNG)" == "1" +CPPFLAGS=$(CPPFLAGS) /DLIBSSH2_WINCNG +# LIBS=bcrypt.lib crypt32.lib +!else +CPPFLAGS=$(CPPFLAGS) /DLIBSSH2_OPENSSL /I$(OPENSSLINC) +LIBS=$(LIBS) $(OPENSSLLIB)\libeay32.lib $(OPENSSLLIB)\ssleay32.lib +!endif + +!if "$(WITH_ZLIB)" == "1" +CPPFLAGS=$(CPPFLAGS) /DLIBSSH2_HAVE_ZLIB /I$(ZLIBINC) +LIBS=$(LIBS) $(ZLIBLIB)\zlib.lib +!endif + +CFLAGS=$(CPPFLAGS) +RCFLAGS=/Iinclude +DLLFLAGS=$(CFLAGS) $(DLLFLAGS) +LIBS=$(LIBS) ws2_32.lib user32.lib advapi32.lib gdi32.lib + +INTDIR=$(TARGET)\$(SUBDIR) + + diff --git a/libssh2/win32/libssh2.dsp b/libssh2/win32/libssh2.dsp new file mode 100644 index 000000000..eac2b82b1 --- /dev/null +++ b/libssh2/win32/libssh2.dsp @@ -0,0 +1,419 @@ +# Microsoft Developer Studio Project File - Name="libssh2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** +# only OpenSSL and WinCNG are supported with this build system + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libssh2 - Win32 OpenSSL Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libssh2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libssh2.mak" CFG="libssh2 - Win32 DLL Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libssh2 - Win32 OpenSSL DLL Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libssh2 - Win32 OpenSSL DLL Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libssh2 - Win32 OpenSSL LIB Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libssh2 - Win32 OpenSSL LIB Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "libssh2 - Win32 WinCNG DLL Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libssh2 - Win32 WinCNG DLL Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libssh2 - Win32 WinCNG LIB Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libssh2 - Win32 WinCNG LIB Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libssh2 - Win32 OpenSSL DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_dll" +# PROP BASE Intermediate_Dir "Release_dll" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_dll" +# PROP Intermediate_Dir "Release_dll" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 gdi32.lib advapi32.lib user32.lib kernel32.lib ws2_32.lib libeay32.lib zlib.lib /nologo /dll /map /debug /machine:I386 + +!ELSEIF "$(CFG)" == "libssh2 - Win32 OpenSSL DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_dll" +# PROP BASE Intermediate_Dir "Debug_dll" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_dll" +# PROP Intermediate_Dir "Debug_dll" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /D "LIBSSH2DEBUG" /YX /FD /GZ /c +# SUBTRACT CPP /WX /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 gdi32.lib advapi32.lib user32.lib kernel32.lib ws2_32.lib libeay32.lib zlib.lib /nologo /dll /incremental:no /map /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "libssh2 - Win32 OpenSSL LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_lib" +# PROP BASE Intermediate_Dir "Release_lib" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_lib" +# PROP Intermediate_Dir "Release_lib" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo +# ADD LIB32 /nologo /out:"Release_lib\libssh2.lib" + +!ELSEIF "$(CFG)" == "libssh2 - Win32 OpenSSL LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_lib" +# PROP BASE Intermediate_Dir "Debug_lib" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_lib" +# PROP Intermediate_Dir "Debug_lib" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /D "LIBSSH2DEBUG" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Debug_lib\libssh2d.lib" + +!ELSEIF "$(CFG)" == "libssh2 - Win32 WinCNG LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_dll" +# PROP BASE Intermediate_Dir "Release_dll" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_dll" +# PROP Intermediate_Dir "Release_dll" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 gdi32.lib advapi32.lib user32.lib kernel32.lib ws2_32.lib crypt32.lib bcrypt.lib /nologo /dll /map /debug /machine:I386 + +!ELSEIF "$(CFG)" == "libssh2 - Win32 WinCNG DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_dll" +# PROP BASE Intermediate_Dir "Debug_dll" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_dll" +# PROP Intermediate_Dir "Debug_dll" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /D "LIBSSH2DEBUG" /YX /FD /GZ /c +# SUBTRACT CPP /WX /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 gdi32.lib advapi32.lib user32.lib kernel32.lib ws2_32.lib crypt32.lib bcrypt.lib /nologo /dll /incremental:no /map /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "libssh2 - Win32 WinCNG LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_lib" +# PROP BASE Intermediate_Dir "Release_lib" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_lib" +# PROP Intermediate_Dir "Release_lib" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo +# ADD LIB32 /nologo /out:"Release_lib\libssh2.lib" + +!ELSEIF "$(CFG)" == "libssh2 - Win32 WinCNG LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_lib" +# PROP BASE Intermediate_Dir "Debug_lib" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_lib" +# PROP Intermediate_Dir "Debug_lib" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /D "LIBSSH2DEBUG" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Debug_lib\libssh2d.lib" + +!ENDIF + +# Begin Target + +# Name "libssh2 - Win32 OpenSSL DLL Release" +# Name "libssh2 - Win32 OpenSSL DLL Debug" +# Name "libssh2 - Win32 OpenSSL LIB Release" +# Name "libssh2 - Win32 OpenSSL LIB Debug" +# Name "libssh2 - Win32 WinCNG DLL Release" +# Name "libssh2 - Win32 WinCNG DLL Debug" +# Name "libssh2 - Win32 WinCNG LIB Release" +# Name "libssh2 - Win32 WinCNG LIB Debug" + +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx" +# Begin Source File + +SOURCE=..\src\agent.c +# End Source File +# Begin Source File + +SOURCE=..\src\channel.c +# End Source File +# Begin Source File + +SOURCE=..\src\comp.c +# End Source File +# Begin Source File + +SOURCE=..\src\crypt.c +# End Source File +# Begin Source File + +SOURCE=..\src\global.c +# End Source File +# Begin Source File + +SOURCE=..\src\hostkey.c +# End Source File +# Begin Source File + +SOURCE=..\src\keepalive.c +# End Source File +# Begin Source File + +SOURCE=..\src\kex.c +# End Source File +# Begin Source File + +SOURCE=..\src\knownhost.c +# End Source File +# Begin Source File + +SOURCE=..\src\mac.c +# End Source File +# Begin Source File + +SOURCE=..\src\mbedtls.c +# End Source File +# Begin Source File + +SOURCE=..\src\misc.c +# End Source File +# Begin Source File + +SOURCE=..\src\openssl.c +# End Source File +# Begin Source File + +SOURCE=..\src\packet.c +# End Source File +# Begin Source File + +SOURCE=..\src\pem.c +# End Source File +# Begin Source File + +SOURCE=..\src\publickey.c +# End Source File +# Begin Source File + +SOURCE=..\src\scp.c +# End Source File +# Begin Source File + +SOURCE=..\src\session.c +# End Source File +# Begin Source File + +SOURCE=..\src\sftp.c +# End Source File +# Begin Source File + +SOURCE=..\src\transport.c +# End Source File +# Begin Source File + +SOURCE=..\src\userauth.c +# End Source File +# Begin Source File + +SOURCE=..\src\version.c +# End Source File +# Begin Source File + +SOURCE=..\src\wincng.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx" +# Begin Source File + +SOURCE=..\src\channel.h +# End Source File +# Begin Source File + +SOURCE=..\src\comp.h +# End Source File +# Begin Source File + +SOURCE=..\src\crypto.h +# End Source File +# Begin Source File + +SOURCE=.\libssh2_config.h +# End Source File +# Begin Source File + +SOURCE=..\src\libssh2_priv.h +# End Source File +# Begin Source File + +SOURCE=..\src\mac.h +# End Source File +# Begin Source File + +SOURCE=..\src\mbedtls.h +# End Source File +# Begin Source File + +SOURCE=..\src\misc.h +# End Source File +# Begin Source File + +SOURCE=..\src\openssl.h +# End Source File +# Begin Source File + +SOURCE=..\src\packet.h +# End Source File +# Begin Source File + +SOURCE=..\src\session.h +# End Source File +# Begin Source File + +SOURCE=..\src\sftp.h +# End Source File +# Begin Source File + +SOURCE=..\src\transport.h +# End Source File +# Begin Source File + +SOURCE=..\src\userauth.h +# End Source File +# Begin Source File + +SOURCE=..\src\wincng.h +# End Source File +# End Group +# End Target +# End Project + diff --git a/libssh2/win32/libssh2.dsw b/libssh2/win32/libssh2.dsw new file mode 100644 index 000000000..36ad8fc0f --- /dev/null +++ b/libssh2/win32/libssh2.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "libssh2"=".\libssh2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "tests"=".\tests.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/libssh2/win32/libssh2.rc b/libssh2/win32/libssh2.rc new file mode 100644 index 000000000..f5d607a72 --- /dev/null +++ b/libssh2/win32/libssh2.rc @@ -0,0 +1,45 @@ +/*************************************************************************** +* libssh2 Win32 resource file * +***************************************************************************/ +#include +#include "../include/libssh2.h" + +LANGUAGE 0x09,0x01 + +#define RC_VERSION LIBSSH2_VERSION_MAJOR, LIBSSH2_VERSION_MINOR, LIBSSH2_VERSION_PATCH, 0 + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RC_VERSION + PRODUCTVERSION RC_VERSION + FILEFLAGSMASK 0x3fL +#if defined(DEBUGBUILD) || defined(_DEBUG) + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The libssh2 library, https://www.libssh2.org/\0" + VALUE "FileDescription", "libssh2 Shared Library\0" + VALUE "FileVersion", LIBSSH2_VERSION "\0" + VALUE "InternalName", "libssh2\0" + VALUE "OriginalFilename", "libssh2.dll\0" + VALUE "ProductName", "The libssh2 library\0" + VALUE "ProductVersion", LIBSSH2_VERSION "\0" + VALUE "LegalCopyright", "© " LIBSSH2_COPYRIGHT "\0" + VALUE "License", "https://www.libssh2.org/license.html\0" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/libssh2/win32/libssh2.sln b/libssh2/win32/libssh2.sln new file mode 100644 index 000000000..a75e4e559 --- /dev/null +++ b/libssh2/win32/libssh2.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libssh2", "libssh2.vcxproj", "{ED957342-E43B-496E-92D9-4C76B525BDF5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + OpenSSL DLL Debug|Win32 = OpenSSL DLL Debug|Win32 + OpenSSL DLL Release|Win32 = OpenSSL DLL Release|Win32 + OpenSSL LIB Debug|Win32 = OpenSSL LIB Debug|Win32 + OpenSSL LIB Release|Win32 = OpenSSL LIB Release|Win32 + WinCNG DLL Debug|Win32 = WinCNG DLL Debug|Win32 + WinCNG DLL Release|Win32 = WinCNG DLL Release|Win32 + WinCNG LIB Debug|Win32 = WinCNG LIB Debug|Win32 + WinCNG LIB Release|Win32 = WinCNG LIB Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ED957342-E43B-496E-92D9-4C76B525BDF5}.OpenSSL DLL Debug|Win32.ActiveCfg = OpenSSL DLL Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.OpenSSL DLL Debug|Win32.Build.0 = OpenSSL DLL Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.OpenSSL DLL Release|Win32.ActiveCfg = OpenSSL DLL Release|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.OpenSSL DLL Release|Win32.Build.0 = OpenSSL DLL Release|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.OpenSSL LIB Debug|Win32.ActiveCfg = OpenSSL LIB Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.OpenSSL LIB Debug|Win32.Build.0 = OpenSSL LIB Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.OpenSSL LIB Release|Win32.ActiveCfg = OpenSSL LIB Release|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.OpenSSL LIB Release|Win32.Build.0 = OpenSSL LIB Release|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.WinCNG DLL Debug|Win32.ActiveCfg = WinCNG DLL Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.WinCNG DLL Debug|Win32.Build.0 = WinCNG DLL Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.WinCNG DLL Release|Win32.ActiveCfg = WinCNG DLL Release|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.WinCNG DLL Release|Win32.Build.0 = WinCNG DLL Release|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.WinCNG LIB Debug|Win32.ActiveCfg = WinCNG LIB Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.WinCNG LIB Debug|Win32.Build.0 = WinCNG LIB Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.WinCNG LIB Release|Win32.ActiveCfg = WinCNG LIB Release|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.WinCNG LIB Release|Win32.Build.0 = WinCNG LIB Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libssh2/win32/libssh2.vcxproj b/libssh2/win32/libssh2.vcxproj new file mode 100644 index 000000000..f696e4ea0 --- /dev/null +++ b/libssh2/win32/libssh2.vcxproj @@ -0,0 +1,194 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + {ED957342-E43B-496E-92D9-4C76B525BDF5} + + + + DynamicLibrary + v120 + false + MultiByte + + + DynamicLibrary + v120 + false + MultiByte + + + + + + + + + + + + + + + .\Release_dll\ + .\Release_dll\ + false + + + .\Debug_dll\ + .\Debug_dll\ + false + + + + MultiThreadedDLL + Default + true + true + MaxSpeed + true + Level3 + ..\..\libz;..\..\..\nmap-mswin32-aux\OpenSSL\include;..\win32;..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;LIBSSH2_WIN32;LIBSSH2_OPENSSL;_LIB;LIBSSH2_LIBRARY;%(PreprocessorDefinitions) + .\Release_dll\ + .\Release_dll\libssh2.pch + .\Release_dll\ + .\Release_dll\ + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Release_dll\libssh2.tlb + true + Win32 + + + 0x0409 + NDEBUG;%(PreprocessorDefinitions) + + + true + .\Release_dll\libssh2.bsc + + + true + true + true + Console + .\Release_dll\libssh2.dll + .\Release_dll\libssh2.lib + ws2_32.lib;libeay32.lib;zlib.lib;%(AdditionalDependencies) + ..\..\libz\contrib\vstudio\vc11\Release_lib;..\..\..\nmap-mswin32-aux\OpenSSL\lib;%(AdditionalLibraryDirectories) + + + + + MultiThreadedDLL + Default + false + Disabled + true + Level3 + false + true + EditAndContinue + ..\..\..\nmap-mswin32-aux\OpenSSL\include;..\..\libzlib128-dll\include;..\win32;..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;LIBSSH2_WIN32;LIBSSH2_OPENSSL;_LIB;LIBSSH2DEBUG;LIBSSH2_LIBRARY;%(PreprocessorDefinitions) + .\Debug_dll\ + .\Debug_dll\libssh2.pch + .\Debug_dll\ + .\Debug_dll\ + EnableFastChecks + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Debug_dll\libssh2.tlb + true + Win32 + + + 0x0409 + _DEBUG;%(PreprocessorDefinitions) + + + true + .\Debug_dll\libssh2.bsc + + + true + true + true + Console + false + .\Debug_dll\libssh2.dll + .\Debug_dll\libssh2.lib + ws2_32.lib;libeay32.lib;zlibd.lib;%(AdditionalDependencies) + ..\..\..\nmap-mswin32-aux\OpenSSL\lib;..\..\libz\contrib\vstudio\vc11\Debug_lib;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + false + false + false + true + false + + + + + + \ No newline at end of file diff --git a/libssh2/win32/libssh2_config.h b/libssh2/win32/libssh2_config.h new file mode 100644 index 000000000..6ac2ef43e --- /dev/null +++ b/libssh2/win32/libssh2_config.h @@ -0,0 +1,47 @@ +#ifndef LIBSSH2_CONFIG_H +#define LIBSSH2_CONFIG_H + +#ifndef WIN32 +#define WIN32 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif /* _CRT_SECURE_NO_DEPRECATE */ +#include +#include +#include + +#ifdef __MINGW32__ +#define HAVE_UNISTD_H +#define HAVE_INTTYPES_H +#define HAVE_SYS_TIME_H +#define HAVE_GETTIMEOFDAY +#endif /* __MINGW32__ */ + +#define HAVE_LIBCRYPT32 +#define HAVE_WINSOCK2_H +#define HAVE_IOCTLSOCKET +#define HAVE_SELECT + +#ifdef _MSC_VER +#if _MSC_VER < 1900 +#define snprintf _snprintf +#if _MSC_VER < 1500 +#define vsnprintf _vsnprintf +#endif +#define strdup _strdup +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif +#else +#ifndef __MINGW32__ +#define strncasecmp strnicmp +#define strcasecmp stricmp +#endif /* __MINGW32__ */ +#endif /* _MSC_VER */ + +/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ +#define LIBSSH2_DH_GEX_NEW 1 + +#endif /* LIBSSH2_CONFIG_H */ + diff --git a/libssh2/win32/msvcproj.foot b/libssh2/win32/msvcproj.foot new file mode 100644 index 000000000..07defa465 --- /dev/null +++ b/libssh2/win32/msvcproj.foot @@ -0,0 +1,3 @@ +# End Target +# End Project + diff --git a/libssh2/win32/msvcproj.head b/libssh2/win32/msvcproj.head new file mode 100644 index 000000000..eb820201d --- /dev/null +++ b/libssh2/win32/msvcproj.head @@ -0,0 +1,256 @@ +# Microsoft Developer Studio Project File - Name="libssh2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** +# only OpenSSL and WinCNG are supported with this build system + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libssh2 - Win32 OpenSSL Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "libssh2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "libssh2.mak" CFG="libssh2 - Win32 DLL Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "libssh2 - Win32 OpenSSL DLL Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libssh2 - Win32 OpenSSL DLL Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libssh2 - Win32 OpenSSL LIB Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libssh2 - Win32 OpenSSL LIB Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "libssh2 - Win32 WinCNG DLL Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libssh2 - Win32 WinCNG DLL Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "libssh2 - Win32 WinCNG LIB Release" (based on "Win32 (x86) Static Library") +!MESSAGE "libssh2 - Win32 WinCNG LIB Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libssh2 - Win32 OpenSSL DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_dll" +# PROP BASE Intermediate_Dir "Release_dll" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_dll" +# PROP Intermediate_Dir "Release_dll" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 gdi32.lib advapi32.lib user32.lib kernel32.lib ws2_32.lib libeay32.lib zlib.lib /nologo /dll /map /debug /machine:I386 + +!ELSEIF "$(CFG)" == "libssh2 - Win32 OpenSSL DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_dll" +# PROP BASE Intermediate_Dir "Debug_dll" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_dll" +# PROP Intermediate_Dir "Debug_dll" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /D "LIBSSH2DEBUG" /YX /FD /GZ /c +# SUBTRACT CPP /WX /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 gdi32.lib advapi32.lib user32.lib kernel32.lib ws2_32.lib libeay32.lib zlib.lib /nologo /dll /incremental:no /map /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "libssh2 - Win32 OpenSSL LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_lib" +# PROP BASE Intermediate_Dir "Release_lib" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_lib" +# PROP Intermediate_Dir "Release_lib" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo +# ADD LIB32 /nologo /out:"Release_lib\libssh2.lib" + +!ELSEIF "$(CFG)" == "libssh2 - Win32 OpenSSL LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_lib" +# PROP BASE Intermediate_Dir "Debug_lib" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_lib" +# PROP Intermediate_Dir "Debug_lib" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_OPENSSL" /D "_MBCS" /D "_LIB" /D "LIBSSH2DEBUG" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Debug_lib\libssh2d.lib" + +!ELSEIF "$(CFG)" == "libssh2 - Win32 WinCNG LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_dll" +# PROP BASE Intermediate_Dir "Release_dll" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_dll" +# PROP Intermediate_Dir "Release_dll" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 gdi32.lib advapi32.lib user32.lib kernel32.lib ws2_32.lib crypt32.lib bcrypt.lib /nologo /dll /map /debug /machine:I386 + +!ELSEIF "$(CFG)" == "libssh2 - Win32 WinCNG DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_dll" +# PROP BASE Intermediate_Dir "Debug_dll" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_dll" +# PROP Intermediate_Dir "Debug_dll" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /D "LIBSSH2DEBUG" /YX /FD /GZ /c +# SUBTRACT CPP /WX /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 gdi32.lib advapi32.lib user32.lib kernel32.lib ws2_32.lib crypt32.lib bcrypt.lib /nologo /dll /incremental:no /map /debug /machine:I386 /pdbtype:sept +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "libssh2 - Win32 WinCNG LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release_lib" +# PROP BASE Intermediate_Dir "Release_lib" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_lib" +# PROP Intermediate_Dir "Release_lib" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo +# ADD LIB32 /nologo /out:"Release_lib\libssh2.lib" + +!ELSEIF "$(CFG)" == "libssh2 - Win32 WinCNG LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug_lib" +# PROP BASE Intermediate_Dir "Debug_lib" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug_lib" +# PROP Intermediate_Dir "Debug_lib" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "LIBSSH2_WINCNG" /D "_MBCS" /D "_LIB" /D "LIBSSH2DEBUG" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Debug_lib\libssh2d.lib" + +!ENDIF + +# Begin Target + +# Name "libssh2 - Win32 OpenSSL DLL Release" +# Name "libssh2 - Win32 OpenSSL DLL Debug" +# Name "libssh2 - Win32 OpenSSL LIB Release" +# Name "libssh2 - Win32 OpenSSL LIB Debug" +# Name "libssh2 - Win32 WinCNG DLL Release" +# Name "libssh2 - Win32 WinCNG DLL Debug" +# Name "libssh2 - Win32 WinCNG LIB Release" +# Name "libssh2 - Win32 WinCNG LIB Debug" + diff --git a/libssh2/win32/rules.mk b/libssh2/win32/rules.mk new file mode 100644 index 000000000..bfb778476 --- /dev/null +++ b/libssh2/win32/rules.mk @@ -0,0 +1,15 @@ + +all-sub: $(INTDIR) all + +clean-sub: clean + +$(INTDIR): +!if "$(SRCDIR)" == "" + @if not exist $(TARGET) mkdir $(TARGET) +!endif + @if not exist $(INTDIR) mkdir $(INTDIR) + +{$(SUBDIR)}.c{$(INTDIR)}.obj:: + $(CC) -c $(CFLAGS) /Fo"$(INTDIR)\\" $< + + diff --git a/libssh2/win32/test/GNUmakefile b/libssh2/win32/test/GNUmakefile new file mode 100644 index 000000000..5cf6e8cf6 --- /dev/null +++ b/libssh2/win32/test/GNUmakefile @@ -0,0 +1,283 @@ +######################################################################### +# +## Makefile for building libssh2 samples (Win32 version - gnu make) +## Use: make -f GNUmakefile [help] +## +## Hacked by: Guenter Knauf +# +######################################################################### + +# Edit the path below to point to the base of your Zlib sources. +ifndef ZLIB_PATH +ZLIB_PATH = ../../../zlib-1.2.8 +endif + +# Edit the path below to point to the base of your OpenSSL package. +ifndef OPENSSL_PATH +OPENSSL_PATH = ../../../openssl-0.9.8zc +endif + +# Project root +PROOT = ../.. + +# Edit the var below to enable static linking of libssh2 and libz +LINK_STATIC = 1 + +# Edit the vars below to change target settings. +SAMPLES = $(PROOT)/example +TARGETS := $(filter-out x11.exe,$(patsubst $(SAMPLES)/%.c,%.exe,$(strip $(wildcard $(SAMPLES)/*.c)))) +WWWURL = https://www.libssh2.org/ +DESCR = libssh2 $(subst .rc,,$(notdir $@)) $(LIBSSH2_VERSION_STR) +#STACK = 64000 + +# must be equal to DEBUG or NDEBUG +ifndef DB + DB = NDEBUG + # DB = DEBUG +endif +# Optimization: -O or debugging: -g +ifeq ($(DB),NDEBUG) + OPT = -O2 + OBJDIR = release +else + OPT = -g + OBJDIR = debug +endif + +# Here you can find a native Win32 binary of the original awk: +# http://www.gknw.net/development/prgtools/awk-20100523.zip +AWK = awk +ZIP = zip -qzr9 + +# Platform-dependent helper tool macros +ifeq ($(findstring /sh,$(SHELL)),/sh) +DEL = rm -f $1 +RMDIR = rm -fr $1 +MKDIR = mkdir -p $1 +COPY = -cp -afv $1 $2 +#COPYR = -cp -afr $1/* $2 +COPYR = -rsync -aC $1/* $2 +TOUCH = touch $1 +CAT = cat +ECHONL = echo "" +DL = ' +else +ifeq "$(OS)" "Windows_NT" +DEL = -del 2>NUL /q /f $(subst /,\,$1) +RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) +else +DEL = -del 2>NUL $(subst /,\,$1) +RMDIR = -deltree 2>NUL /y $(subst /,\,$1) +endif +MKDIR = -md 2>NUL $(subst /,\,$1) +COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) +COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2) +TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,, +CAT = type +ECHONL = $(ComSpec) /c echo. +endif + +# The following line defines your compiler. +ifdef METROWERKS + CC = mwcc +else + CC = $(CROSSPREFIX)gcc +endif + +# Set environment var ARCH to your architecture to override autodetection. +ifndef ARCH +ifeq ($(findstring gcc,$(CC)),gcc) +ifeq ($(findstring x86_64,$(shell $(CC) -dumpmachine)),x86_64) +ARCH = w64 +else +ARCH = w32 +endif +else +ARCH = w32 +endif +endif + +# Include the version info retrieved from libssh2.h +-include $(OBJDIR)/version.inc + +# Global flags for all compilers +CFLAGS = $(OPT) -D$(DB) -DLIBSSH2_WIN32 # -DHAVE_CONFIG_H + +ifeq ($(CC),mwcc) +LD = mwld +RC = mwwinrc +LDFLAGS = -nostdlib +AR = $(LD) +ARFLAGS = -nostdlib -library -o +LIBEXT = lib +LIBPATH += -lr "$(METROWERKS)/MSL" -lr "$(METROWERKS)/Win32-x86 Support" +LDLIBS += -lMSL_Runtime_x86.lib -lMSL_C_x86.lib -lMSL_Extras_x86.lib +LDLIBS += -lkernel32.lib -luser32.lib -lwsock32.lib +RCFLAGS = +CFLAGS += -nostdinc -gccinc -msgstyle gcc -inline off -opt nointrinsics -proc 586 +CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support" +CFLAGS += -w on,nounused,nounusedexpr # -ansi strict +else +LD = $(CROSSPREFIX)gcc +RC = $(CROSSPREFIX)windres +LDFLAGS = -s +AR = $(CROSSPREFIX)ar +ARFLAGS = -cq +LIBEXT = a +#LDLIBS += -lwsock32 +LDLIBS += -lws2_32 +RCFLAGS = -I $(PROOT)/include -O coff +CFLAGS += -fno-builtin +CFLAGS += -fno-strict-aliasing +CFLAGS += -Wall #-Wno-unused #-pedantic +ifeq ($(ARCH),w64) +CFLAGS += -D_AMD64_ +RCFLAGS += -F pe-x86-64 +else +CFLAGS += -m32 +RCFLAGS += -F pe-i386 +endif +endif + +INCLUDES = -I$(PROOT)/win32 -I$(PROOT)/include +LIBPATH += -L$(PROOT)/win32 + +ifdef LINK_STATIC + LDLIBS += -llibssh2 +else + LDLIBS += -llibssh2dll +endif + +ifdef WITH_WINCNG +# CFLAGS += -DLIBSSH2_WINCNG +LDLIBS += -lbcrypt -lcrypt32 +else +# CFLAGS += -DLIBSSH2_OPENSSL +ifndef OPENSSL_INCLUDE + ifeq "$(wildcard $(OPENSSL_PATH)/outinc)" "$(OPENSSL_PATH)/outinc" + OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc + endif + ifeq "$(wildcard $(OPENSSL_PATH)/include)" "$(OPENSSL_PATH)/include" + OPENSSL_INCLUDE = $(OPENSSL_PATH)/include + endif +endif +ifneq "$(wildcard $(OPENSSL_INCLUDE)/openssl/opensslv.h)" "$(OPENSSL_INCLUDE)/openssl/opensslv.h" +$(error Invalid OPENSSL_PATH: $(OPENSSL_PATH)) +endif +INCLUDES += -I"$(OPENSSL_INCLUDE)" +ifndef OPENSSL_LIBPATH + OPENSSL_LIBS_STAT = crypto ssl + ifeq "$(wildcard $(OPENSSL_PATH)/out)" "$(OPENSSL_PATH)/out" + OPENSSL_LIBPATH = $(OPENSSL_PATH)/out + OPENSSL_LIBS_DYN = eay32 ssl32 + endif + ifeq "$(wildcard $(OPENSSL_PATH)/lib)" "$(OPENSSL_PATH)/lib" + OPENSSL_LIBPATH = $(OPENSSL_PATH)/lib + OPENSSL_LIBS_DYN = crypto.dll ssl.dll + endif +endif +ifdef LINK_STATIC +ifdef LINK_OPENSSL_STATIC + LDLIBS += $(patsubst %,$(OPENSSL_LIBPATH)/lib%.$(LIBEXT), $(OPENSSL_LIBS_STAT)) -lgdi32 +else + LDLIBS += $(patsubst %,$(OPENSSL_LIBPATH)/lib%.$(LIBEXT), $(OPENSSL_LIBS_DYN)) +endif +endif +endif + +ifdef WITH_ZLIB + CFLAGS += -DLIBSSH2_HAVE_ZLIB + INCLUDES += -I$(ZLIB_PATH) + ifdef LINK_ZLIB_STATIC + LDLIBS += $(ZLIB_PATH)/libz.$(LIBEXT) + else + LDLIBS += $(ZLIB_PATH)/libzdll.$(LIBEXT) + endif +endif + +CFLAGS += $(INCLUDES) + +vpath %.c $(PROOT)/example + +.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.rc $(OBJDIR)/%.res + + +all: prebuild $(TARGETS) + +prebuild: $(OBJDIR) $(OBJDIR)/version.inc + +$(OBJDIR)/%.o: %.c +# @echo Compiling $< + $(CC) $(CFLAGS) -c $< -o $@ + +$(OBJDIR)/version.inc: $(PROOT)/include/libssh2.h $(OBJDIR) + @echo Creating $@ + @$(AWK) -f $(PROOT)/get_ver.awk $< > $@ + +objclean: + $(call RMDIR, $(OBJDIR)) + +clean: objclean + $(call DEL, $(TARGETS)) + +$(OBJDIR): + $(call MKDIR, $@) + +%.exe: $(OBJDIR)/%.o $(OBJDIR)/%.res + @echo Linking $@ + @$(call DEL, $@) + $(LD) $(LDFLAGS) $^ -o $@ $(LIBPATH) $(LDLIBS) + +$(OBJDIR)/%.res: $(OBJDIR)/%.rc + @echo Creating $@ + @$(RC) $(RCFLAGS) -i $< -o $@ + +$(OBJDIR)/%.rc: GNUmakefile $(OBJDIR)/version.inc + @echo $(DL)1 VERSIONINFO$(DL) > $@ + @echo $(DL) FILEVERSION $(LIBSSH2_VERSION),0$(DL) >> $@ + @echo $(DL) PRODUCTVERSION $(LIBSSH2_VERSION),0$(DL) >> $@ + @echo $(DL) FILEFLAGSMASK 0x3fL$(DL) >> $@ + @echo $(DL) FILEOS 0x40004L$(DL) >> $@ + @echo $(DL) FILEFLAGS 0x0L$(DL) >> $@ + @echo $(DL) FILETYPE 0x1L$(DL) >> $@ + @echo $(DL) FILESUBTYPE 0x0L$(DL) >> $@ + @echo $(DL)BEGIN$(DL) >> $@ + @echo $(DL) BLOCK "StringFileInfo"$(DL) >> $@ + @echo $(DL) BEGIN$(DL) >> $@ + @echo $(DL) BLOCK "040904E4"$(DL) >> $@ + @echo $(DL) BEGIN$(DL) >> $@ + @echo $(DL) VALUE "LegalCopyright","\xA9 $(LIBSSH2_COPYRIGHT_STR)\0"$(DL) >> $@ +ifdef COMPANY + @echo $(DL) VALUE "CompanyName","$(COMPANY)\0"$(DL) >> $@ +endif + @echo $(DL) VALUE "ProductName","$(notdir $(@:.rc=.exe))\0"$(DL) >> $@ + @echo $(DL) VALUE "ProductVersion","$(LIBSSH2_VERSION_STR)\0"$(DL) >> $@ + @echo $(DL) VALUE "License","Released under GPL.\0"$(DL) >> $@ + @echo $(DL) VALUE "FileDescription","$(DESCR)\0"$(DL) >> $@ + @echo $(DL) VALUE "FileVersion","$(LIBSSH2_VERSION_STR)\0"$(DL) >> $@ + @echo $(DL) VALUE "InternalName","$(notdir $(@:.rc=))\0"$(DL) >> $@ + @echo $(DL) VALUE "OriginalFilename","$(notdir $(@:.rc=.exe))\0"$(DL) >> $@ + @echo $(DL) VALUE "WWW","$(WWWURL)\0"$(DL) >> $@ + @echo $(DL) END$(DL) >> $@ + @echo $(DL) END$(DL) >> $@ + @echo $(DL) BLOCK "VarFileInfo"$(DL) >> $@ + @echo $(DL) BEGIN$(DL) >> $@ + @echo $(DL) VALUE "Translation", 0x409, 1252$(DL) >> $@ + @echo $(DL) END$(DL) >> $@ + @echo $(DL)END$(DL) >> $@ +ifdef ICON + @echo $(DL)10 ICON DISCARDABLE "$(ICON)"$(DL) >> $@ +endif + +help: $(OBJDIR)/version.inc + @echo $(DL)===========================================================$(DL) + @echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL) + @echo $(DL)Zlib path = $(ZLIB_PATH)$(DL) + @echo $(DL)===========================================================$(DL) + @echo $(DL)libssh $(LIBSSH2_VERSION_STR) - available targets are:$(DL) + @echo $(DL)$(MAKE) all$(DL) + @echo $(DL)$(MAKE) clean$(DL) + @echo $(DL)$(MAKE) objclean$(DL) + @echo $(DL)===========================================================$(DL) + + diff --git a/libssh2/win32/tests.dsp b/libssh2/win32/tests.dsp new file mode 100644 index 000000000..b6df32418 --- /dev/null +++ b/libssh2/win32/tests.dsp @@ -0,0 +1,102 @@ +# Microsoft Developer Studio Project File - Name="tests" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=tests - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "tests.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "tests.mak" CFG="tests - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "tests - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "tests - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "tests - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "tests___Win32_Release" +# PROP BASE Intermediate_Dir "tests___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\include" /I "..\win32" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libeay32.lib ssleay32.lib ws2_32.lib zlib.lib libssh2.lib /nologo /subsystem:console /machine:I386 /libpath:"Release" /out:"simple.exe" + +!ELSEIF "$(CFG)" == "tests - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "tests___Win32_Debug" +# PROP BASE Intermediate_Dir "tests___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\win32" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libeay32.lib ssleay32.lib ws2_32.lib zlib.lib libssh2d.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"Debug" /out:"simple.exe" + +!ENDIF + +# Begin Target + +# Name "tests - Win32 Release" +# Name "tests - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\tests\simple.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/libz/CMakeLists.txt b/libz/CMakeLists.txt new file mode 100644 index 000000000..0c0247cc5 --- /dev/null +++ b/libz/CMakeLists.txt @@ -0,0 +1,249 @@ +cmake_minimum_required(VERSION 2.4.4) +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) + +project(zlib C) + +set(VERSION "1.2.8") + +option(ASM686 "Enable building i686 assembly implementation") +option(AMD64 "Enable building amd64 assembly implementation") + +set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") +set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") +set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") +set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") +set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") + +include(CheckTypeSize) +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckCSourceCompiles) +enable_testing() + +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(stddef.h HAVE_STDDEF_H) + +# +# Check to see if we have large file support +# +set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) +# We add these other definitions here because CheckTypeSize.cmake +# in CMake 2.4.x does not automatically do so and we want +# compatibility with CMake 2.4.x. +if(HAVE_SYS_TYPES_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) +endif() +if(HAVE_STDINT_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) +endif() +if(HAVE_STDDEF_H) + list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) +endif() +check_type_size(off64_t OFF64_T) +if(HAVE_OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) # clear variable + +# +# Check for fseeko +# +check_function_exists(fseeko HAVE_FSEEKO) +if(NOT HAVE_FSEEKO) + add_definitions(-DNO_FSEEKO) +endif() + +# +# Check for unistd.h +# +check_include_file(unistd.h Z_HAVE_UNISTD_H) + +if(MSVC) + set(CMAKE_DEBUG_POSTFIX "d") + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +endif() + +if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) + # If we're doing an out of source build and the user has a zconf.h + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) + message(STATUS "Renaming") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h") + message(STATUS "to 'zconf.h.included' because this file is included with zlib") + message(STATUS "but CMake generates it automatically in the build directory.") + file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) + endif() +endif() + +set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein + ${ZLIB_PC} @ONLY) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) + + +#============================================================================ +# zlib +#============================================================================ + +set(ZLIB_PUBLIC_HDRS + ${CMAKE_CURRENT_BINARY_DIR}/zconf.h + zlib.h +) +set(ZLIB_PRIVATE_HDRS + crc32.h + deflate.h + gzguts.h + inffast.h + inffixed.h + inflate.h + inftrees.h + trees.h + zutil.h +) +set(ZLIB_SRCS + adler32.c + compress.c + crc32.c + deflate.c + gzclose.c + gzlib.c + gzread.c + gzwrite.c + inflate.c + infback.c + inftrees.c + inffast.c + trees.c + uncompr.c + zutil.c +) + +if(NOT MINGW) + set(ZLIB_DLL_SRCS + win32/zlib1.rc # If present will override custom build rule below. + ) +endif() + +if(CMAKE_COMPILER_IS_GNUCC) + if(ASM686) + set(ZLIB_ASMS contrib/asm686/match.S) + elseif (AMD64) + set(ZLIB_ASMS contrib/amd64/amd64-match.S) + endif () + + if(ZLIB_ASMS) + add_definitions(-DASMV) + set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE) + endif() +endif() + +if(MSVC) + if(ASM686) + ENABLE_LANGUAGE(ASM_MASM) + set(ZLIB_ASMS + contrib/masmx86/inffas32.asm + contrib/masmx86/match686.asm + ) + elseif (AMD64) + ENABLE_LANGUAGE(ASM_MASM) + set(ZLIB_ASMS + contrib/masmx64/gvmat64.asm + contrib/masmx64/inffasx64.asm + ) + endif() + + if(ZLIB_ASMS) + add_definitions(-DASMV -DASMINF) + endif() +endif() + +# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) +string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" + "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) + +if(MINGW) + # This gets us DLL resource information when compiling on MinGW. + if(NOT CMAKE_RC_COMPILER) + set(CMAKE_RC_COMPILER windres.exe) + endif() + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj + COMMAND ${CMAKE_RC_COMPILER} + -D GCC_WINDRES + -I ${CMAKE_CURRENT_SOURCE_DIR} + -I ${CMAKE_CURRENT_BINARY_DIR} + -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj + -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) + set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) +endif(MINGW) + +add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) +set_target_properties(zlib PROPERTIES SOVERSION 1) + +if(NOT CYGWIN) + # This property causes shared libraries on Linux to have the full version + # encoded into their final filename. We disable this on Cygwin because + # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll + # seems to be the default. + # + # This has no effect with MSVC, on that platform the version info for + # the DLL comes from the resource file win32/zlib1.rc + set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) +endif() + +if(UNIX) + # On unix-like platforms the library is almost always called libz + set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) + if(NOT APPLE) + set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") + endif() +elseif(BUILD_SHARED_LIBS AND WIN32) + # Creates zlib1.dll when building shared library version + set_target_properties(zlib PROPERTIES SUFFIX "1.dll") +endif() + +if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) + install(TARGETS zlib zlibstatic + RUNTIME DESTINATION "${INSTALL_BIN_DIR}" + ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" + LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) +endif() +if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) + install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}") +endif() +if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) + install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3") +endif() +if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) + install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}") +endif() + +#============================================================================ +# Example binaries +#============================================================================ + +add_executable(example test/example.c) +target_link_libraries(example zlib) +add_test(example example) + +add_executable(minigzip test/minigzip.c) +target_link_libraries(minigzip zlib) + +if(HAVE_OFF64_T) + add_executable(example64 test/example.c) + target_link_libraries(example64 zlib) + set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") + add_test(example64 example64) + + add_executable(minigzip64 test/minigzip.c) + target_link_libraries(minigzip64 zlib) + set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") +endif() diff --git a/libz/ChangeLog b/libz/ChangeLog new file mode 100644 index 000000000..f22aabaef --- /dev/null +++ b/libz/ChangeLog @@ -0,0 +1,1472 @@ + + ChangeLog file for zlib + +Changes in 1.2.8 (28 Apr 2013) +- Update contrib/minizip/iowin32.c for Windows RT [Vollant] +- Do not force Z_CONST for C++ +- Clean up contrib/vstudio [Ro§] +- Correct spelling error in zlib.h +- Fix mixed line endings in contrib/vstudio + +Changes in 1.2.7.3 (13 Apr 2013) +- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc + +Changes in 1.2.7.2 (13 Apr 2013) +- Change check for a four-byte type back to hexadecimal +- Fix typo in win32/Makefile.msc +- Add casts in gzwrite.c for pointer differences + +Changes in 1.2.7.1 (24 Mar 2013) +- Replace use of unsafe string functions with snprintf if available +- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] +- Fix gzgetc undefine when Z_PREFIX set [Turk] +- Eliminate use of mktemp in Makefile (not always available) +- Fix bug in 'F' mode for gzopen() +- Add inflateGetDictionary() function +- Correct comment in deflate.h +- Use _snprintf for snprintf in Microsoft C +- On Darwin, only use /usr/bin/libtool if libtool is not Apple +- Delete "--version" file if created by "ar --version" [Richard G.] +- Fix configure check for veracity of compiler error return codes +- Fix CMake compilation of static lib for MSVC2010 x64 +- Remove unused variable in infback9.c +- Fix argument checks in gzlog_compress() and gzlog_write() +- Clean up the usage of z_const and respect const usage within zlib +- Clean up examples/gzlog.[ch] comparisons of different types +- Avoid shift equal to bits in type (caused endless loop) +- Fix unintialized value bug in gzputc() introduced by const patches +- Fix memory allocation error in examples/zran.c [Nor] +- Fix bug where gzopen(), gzclose() would write an empty file +- Fix bug in gzclose() when gzwrite() runs out of memory +- Check for input buffer malloc failure in examples/gzappend.c +- Add note to contrib/blast to use binary mode in stdio +- Fix comparisons of differently signed integers in contrib/blast +- Check for invalid code length codes in contrib/puff +- Fix serious but very rare decompression bug in inftrees.c +- Update inflateBack() comments, since inflate() can be faster +- Use underscored I/O function names for WINAPI_FAMILY +- Add _tr_flush_bits to the external symbols prefixed by --zprefix +- Add contrib/vstudio/vc10 pre-build step for static only +- Quote --version-script argument in CMakeLists.txt +- Don't specify --version-script on Apple platforms in CMakeLists.txt +- Fix casting error in contrib/testzlib/testzlib.c +- Fix types in contrib/minizip to match result of get_crc_table() +- Simplify contrib/vstudio/vc10 with 'd' suffix +- Add TOP support to win32/Makefile.msc +- Suport i686 and amd64 assembler builds in CMakeLists.txt +- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h +- Add vc11 and vc12 build files to contrib/vstudio +- Add gzvprintf() as an undocumented function in zlib +- Fix configure for Sun shell +- Remove runtime check in configure for four-byte integer type +- Add casts and consts to ease user conversion to C++ +- Add man pages for minizip and miniunzip +- In Makefile uninstall, don't rm if preceding cd fails +- Do not return Z_BUF_ERROR if deflateParam() has nothing to write + +Changes in 1.2.7 (2 May 2012) +- Replace use of memmove() with a simple copy for portability +- Test for existence of strerror +- Restore gzgetc_ for backward compatibility with 1.2.6 +- Fix build with non-GNU make on Solaris +- Require gcc 4.0 or later on Mac OS X to use the hidden attribute +- Include unistd.h for Watcom C +- Use __WATCOMC__ instead of __WATCOM__ +- Do not use the visibility attribute if NO_VIZ defined +- Improve the detection of no hidden visibility attribute +- Avoid using __int64 for gcc or solo compilation +- Cast to char * in gzprintf to avoid warnings [Zinser] +- Fix make_vms.com for VAX [Zinser] +- Don't use library or built-in byte swaps +- Simplify test and use of gcc hidden attribute +- Fix bug in gzclose_w() when gzwrite() fails to allocate memory +- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() +- Fix bug in test/minigzip.c for configure --solo +- Fix contrib/vstudio project link errors [Mohanathas] +- Add ability to choose the builder in make_vms.com [Schweda] +- Add DESTDIR support to mingw32 win32/Makefile.gcc +- Fix comments in win32/Makefile.gcc for proper usage +- Allow overriding the default install locations for cmake +- Generate and install the pkg-config file with cmake +- Build both a static and a shared version of zlib with cmake +- Include version symbols for cmake builds +- If using cmake with MSVC, add the source directory to the includes +- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] +- Move obsolete emx makefile to old [Truta] +- Allow the use of -Wundef when compiling or using zlib +- Avoid the use of the -u option with mktemp +- Improve inflate() documentation on the use of Z_FINISH +- Recognize clang as gcc +- Add gzopen_w() in Windows for wide character path names +- Rename zconf.h in CMakeLists.txt to move it out of the way +- Add source directory in CMakeLists.txt for building examples +- Look in build directory for zlib.pc in CMakeLists.txt +- Remove gzflags from zlibvc.def in vc9 and vc10 +- Fix contrib/minizip compilation in the MinGW environment +- Update ./configure for Solaris, support --64 [Mooney] +- Remove -R. from Solaris shared build (possible security issue) +- Avoid race condition for parallel make (-j) running example +- Fix type mismatch between get_crc_table() and crc_table +- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] +- Fix the path to zlib.map in CMakeLists.txt +- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] +- Add instructions to win32/Makefile.gcc for shared install [Torri] + +Changes in 1.2.6.1 (12 Feb 2012) +- Avoid the use of the Objective-C reserved name "id" +- Include io.h in gzguts.h for Microsoft compilers +- Fix problem with ./configure --prefix and gzgetc macro +- Include gz_header definition when compiling zlib solo +- Put gzflags() functionality back in zutil.c +- Avoid library header include in crc32.c for Z_SOLO +- Use name in GCC_CLASSIC as C compiler for coverage testing, if set +- Minor cleanup in contrib/minizip/zip.c [Vollant] +- Update make_vms.com [Zinser] +- Remove unnecessary gzgetc_ function +- Use optimized byte swap operations for Microsoft and GNU [Snyder] +- Fix minor typo in zlib.h comments [Rzesniowiecki] + +Changes in 1.2.6 (29 Jan 2012) +- Update the Pascal interface in contrib/pascal +- Fix function numbers for gzgetc_ in zlibvc.def files +- Fix configure.ac for contrib/minizip [Schiffer] +- Fix large-entry detection in minizip on 64-bit systems [Schiffer] +- Have ./configure use the compiler return code for error indication +- Fix CMakeLists.txt for cross compilation [McClure] +- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] +- Fix compilation of contrib/minizip on FreeBSD [Marquez] +- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] +- Include io.h for Turbo C / Borland C on all platforms [Truta] +- Make version explicit in contrib/minizip/configure.ac [Bosmans] +- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] +- Minor cleanup up contrib/minizip/unzip.c [Vollant] +- Fix bug when compiling minizip with C++ [Vollant] +- Protect for long name and extra fields in contrib/minizip [Vollant] +- Avoid some warnings in contrib/minizip [Vollant] +- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip +- Add missing libs to minizip linker command +- Add support for VPATH builds in contrib/minizip +- Add an --enable-demos option to contrib/minizip/configure +- Add the generation of configure.log by ./configure +- Exit when required parameters not provided to win32/Makefile.gcc +- Have gzputc return the character written instead of the argument +- Use the -m option on ldconfig for BSD systems [Tobias] +- Correct in zlib.map when deflateResetKeep was added + +Changes in 1.2.5.3 (15 Jan 2012) +- Restore gzgetc function for binary compatibility +- Do not use _lseeki64 under Borland C++ [Truta] +- Update win32/Makefile.msc to build test/*.c [Truta] +- Remove old/visualc6 given CMakefile and other alternatives +- Update AS400 build files and documentation [Monnerat] +- Update win32/Makefile.gcc to build test/*.c [Truta] +- Permit stronger flushes after Z_BLOCK flushes +- Avoid extraneous empty blocks when doing empty flushes +- Permit Z_NULL arguments to deflatePending +- Allow deflatePrime() to insert bits in the middle of a stream +- Remove second empty static block for Z_PARTIAL_FLUSH +- Write out all of the available bits when using Z_BLOCK +- Insert the first two strings in the hash table after a flush + +Changes in 1.2.5.2 (17 Dec 2011) +- fix ld error: unable to find version dependency 'ZLIB_1.2.5' +- use relative symlinks for shared libs +- Avoid searching past window for Z_RLE strategy +- Assure that high-water mark initialization is always applied in deflate +- Add assertions to fill_window() in deflate.c to match comments +- Update python link in README +- Correct spelling error in gzread.c +- Fix bug in gzgets() for a concatenated empty gzip stream +- Correct error in comment for gz_make() +- Change gzread() and related to ignore junk after gzip streams +- Allow gzread() and related to continue after gzclearerr() +- Allow gzrewind() and gzseek() after a premature end-of-file +- Simplify gzseek() now that raw after gzip is ignored +- Change gzgetc() to a macro for speed (~40% speedup in testing) +- Fix gzclose() to return the actual error last encountered +- Always add large file support for windows +- Include zconf.h for windows large file support +- Include zconf.h.cmakein for windows large file support +- Update zconf.h.cmakein on make distclean +- Merge vestigial vsnprintf determination from zutil.h to gzguts.h +- Clarify how gzopen() appends in zlib.h comments +- Correct documentation of gzdirect() since junk at end now ignored +- Add a transparent write mode to gzopen() when 'T' is in the mode +- Update python link in zlib man page +- Get inffixed.h and MAKEFIXED result to match +- Add a ./config --solo option to make zlib subset with no libary use +- Add undocumented inflateResetKeep() function for CAB file decoding +- Add --cover option to ./configure for gcc coverage testing +- Add #define ZLIB_CONST option to use const in the z_stream interface +- Add comment to gzdopen() in zlib.h to use dup() when using fileno() +- Note behavior of uncompress() to provide as much data as it can +- Add files in contrib/minizip to aid in building libminizip +- Split off AR options in Makefile.in and configure +- Change ON macro to Z_ARG to avoid application conflicts +- Facilitate compilation with Borland C++ for pragmas and vsnprintf +- Include io.h for Turbo C / Borland C++ +- Move example.c and minigzip.c to test/ +- Simplify incomplete code table filling in inflate_table() +- Remove code from inflate.c and infback.c that is impossible to execute +- Test the inflate code with full coverage +- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) +- Add deflateResetKeep and fix inflateResetKeep to retain dictionary +- Fix gzwrite.c to accommodate reduced memory zlib compilation +- Have inflate() with Z_FINISH avoid the allocation of a window +- Do not set strm->adler when doing raw inflate +- Fix gzeof() to behave just like feof() when read is not past end of file +- Fix bug in gzread.c when end-of-file is reached +- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF +- Document gzread() capability to read concurrently written files +- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] + +Changes in 1.2.5.1 (10 Sep 2011) +- Update FAQ entry on shared builds (#13) +- Avoid symbolic argument to chmod in Makefile.in +- Fix bug and add consts in contrib/puff [Oberhumer] +- Update contrib/puff/zeros.raw test file to have all block types +- Add full coverage test for puff in contrib/puff/Makefile +- Fix static-only-build install in Makefile.in +- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] +- Add libz.a dependency to shared in Makefile.in for parallel builds +- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out +- Replace $(...) with `...` in configure for non-bash sh [Bowler] +- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] +- Add solaris* to Linux* in configure to allow gcc use [Groffen] +- Add *bsd* to Linux* case in configure [Bar-Lev] +- Add inffast.obj to dependencies in win32/Makefile.msc +- Correct spelling error in deflate.h [Kohler] +- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc +- Add test to configure for GNU C looking for gcc in output of $cc -v +- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] +- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not +- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense +- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) +- Make stronger test in zconf.h to include unistd.h for LFS +- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] +- Fix zlib.h LFS support when Z_PREFIX used +- Add updated as400 support (removed from old) [Monnerat] +- Avoid deflate sensitivity to volatile input data +- Avoid division in adler32_combine for NO_DIVIDE +- Clarify the use of Z_FINISH with deflateBound() amount of space +- Set binary for output file in puff.c +- Use u4 type for crc_table to avoid conversion warnings +- Apply casts in zlib.h to avoid conversion warnings +- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] +- Improve inflateSync() documentation to note indeterminancy +- Add deflatePending() function to return the amount of pending output +- Correct the spelling of "specification" in FAQ [Randers-Pehrson] +- Add a check in configure for stdarg.h, use for gzprintf() +- Check that pointers fit in ints when gzprint() compiled old style +- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] +- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] +- Add debug records in assmebler code [Londer] +- Update RFC references to use http://tools.ietf.org/html/... [Li] +- Add --archs option, use of libtool to configure for Mac OS X [Borstel] + +Changes in 1.2.5 (19 Apr 2010) +- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] +- Default to libdir as sharedlibdir in configure [Nieder] +- Update copyright dates on modified source files +- Update trees.c to be able to generate modified trees.h +- Exit configure for MinGW, suggesting win32/Makefile.gcc +- Check for NULL path in gz_open [Homurlu] + +Changes in 1.2.4.5 (18 Apr 2010) +- Set sharedlibdir in configure [Torok] +- Set LDFLAGS in Makefile.in [Bar-Lev] +- Avoid mkdir objs race condition in Makefile.in [Bowler] +- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays +- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C +- Don't use hidden attribute when it is a warning generator (e.g. Solaris) + +Changes in 1.2.4.4 (18 Apr 2010) +- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] +- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty +- Try to use bash or ksh regardless of functionality of /bin/sh +- Fix configure incompatibility with NetBSD sh +- Remove attempt to run under bash or ksh since have better NetBSD fix +- Fix win32/Makefile.gcc for MinGW [Bar-Lev] +- Add diagnostic messages when using CROSS_PREFIX in configure +- Added --sharedlibdir option to configure [Weigelt] +- Use hidden visibility attribute when available [Frysinger] + +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + +Changes in 1.2.4.1 (28 Mar 2010) +- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] +- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] +- Restore "for debugging" comment on sprintf() in gzlib.c +- Remove fdopen for MVS from gzguts.h +- Put new README-WIN32.txt in win32 [Rowe] +- Add check for shell to configure and invoke another shell if needed +- Fix big fat stinking bug in gzseek() on uncompressed files +- Remove vestigial F_OPEN64 define in zutil.h +- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE +- Avoid errors on non-LFS systems when applications define LFS macros +- Set EXE to ".exe" in configure for MINGW [Kahle] +- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] +- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] +- Add DLL install in win32/makefile.gcc [Bar-Lev] +- Allow Linux* or linux* from uname in configure [Bar-Lev] +- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] +- Add cross-compilation prefixes to configure [Bar-Lev] +- Match type exactly in gz_load() invocation in gzread.c +- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func +- Provide prototypes for *64 functions when building zlib without LFS +- Don't use -lc when linking shared library on MinGW +- Remove errno.h check in configure and vestigial errno code in zutil.h + +Changes in 1.2.4 (14 Mar 2010) +- Fix VER3 extraction in configure for no fourth subversion +- Update zlib.3, add docs to Makefile.in to make .pdf out of it +- Add zlib.3.pdf to distribution +- Don't set error code in gzerror() if passed pointer is NULL +- Apply destination directory fixes to CMakeLists.txt [Lowman] +- Move #cmakedefine's to a new zconf.in.cmakein +- Restore zconf.h for builds that don't use configure or cmake +- Add distclean to dummy Makefile for convenience +- Update and improve INDEX, README, and FAQ +- Update CMakeLists.txt for the return of zconf.h [Lowman] +- Update contrib/vstudio/vc9 and vc10 [Vollant] +- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc +- Apply license and readme changes to contrib/asm686 [Raiter] +- Check file name lengths and add -c option in minigzip.c [Li] +- Update contrib/amd64 and contrib/masmx86/ [Vollant] +- Avoid use of "eof" parameter in trees.c to not shadow library variable +- Update make_vms.com for removal of zlibdefs.h [Zinser] +- Update assembler code and vstudio projects in contrib [Vollant] +- Remove outdated assembler code contrib/masm686 and contrib/asm586 +- Remove old vc7 and vc8 from contrib/vstudio +- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] +- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() +- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] +- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) +- Fix bug in void-returning vsprintf() case in gzwrite.c +- Fix name change from inflate.h in contrib/inflate86/inffas86.c +- Check if temporary file exists before removing in make_vms.com [Zinser] +- Fix make install and uninstall for --static option +- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] +- Update readme.txt in contrib/masmx64 and masmx86 to assemble + +Changes in 1.2.3.9 (21 Feb 2010) +- Expunge gzio.c +- Move as400 build information to old +- Fix updates in contrib/minizip and contrib/vstudio +- Add const to vsnprintf test in configure to avoid warnings [Weigelt] +- Delete zconf.h (made by configure) [Weigelt] +- Change zconf.in.h to zconf.h.in per convention [Weigelt] +- Check for NULL buf in gzgets() +- Return empty string for gzgets() with len == 1 (like fgets()) +- Fix description of gzgets() in zlib.h for end-of-file, NULL return +- Update minizip to 1.1 [Vollant] +- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c +- Note in zlib.h that gzerror() should be used to distinguish from EOF +- Remove use of snprintf() from gzlib.c +- Fix bug in gzseek() +- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] +- Fix zconf.h generation in CMakeLists.txt [Lowman] +- Improve comments in zconf.h where modified by configure + +Changes in 1.2.3.8 (13 Feb 2010) +- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] +- Use z_off64_t in gz_zero() and gz_skip() to match state->skip +- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) +- Revert to Makefile.in from 1.2.3.6 (live with the clutter) +- Fix missing error return in gzflush(), add zlib.h note +- Add *64 functions to zlib.map [Levin] +- Fix signed/unsigned comparison in gz_comp() +- Use SFLAGS when testing shared linking in configure +- Add --64 option to ./configure to use -m64 with gcc +- Fix ./configure --help to correctly name options +- Have make fail if a test fails [Levin] +- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] +- Remove assembler object files from contrib + +Changes in 1.2.3.7 (24 Jan 2010) +- Always gzopen() with O_LARGEFILE if available +- Fix gzdirect() to work immediately after gzopen() or gzdopen() +- Make gzdirect() more precise when the state changes while reading +- Improve zlib.h documentation in many places +- Catch memory allocation failure in gz_open() +- Complete close operation if seek forward in gzclose_w() fails +- Return Z_ERRNO from gzclose_r() if close() fails +- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL +- Return zero for gzwrite() errors to match zlib.h description +- Return -1 on gzputs() error to match zlib.h description +- Add zconf.in.h to allow recovery from configure modification [Weigelt] +- Fix static library permissions in Makefile.in [Weigelt] +- Avoid warnings in configure tests that hide functionality [Weigelt] +- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] +- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] +- Avoid access of uninitialized data for first inflateReset2 call [Gomes] +- Keep object files in subdirectories to reduce the clutter somewhat +- Remove default Makefile and zlibdefs.h, add dummy Makefile +- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ +- Remove zlibdefs.h completely -- modify zconf.h instead + +Changes in 1.2.3.6 (17 Jan 2010) +- Avoid void * arithmetic in gzread.c and gzwrite.c +- Make compilers happier with const char * for gz_error message +- Avoid unused parameter warning in inflate.c +- Avoid signed-unsigned comparison warning in inflate.c +- Indent #pragma's for traditional C +- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() +- Correct email address in configure for system options +- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] +- Update zlib.map [Brown] +- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] +- Apply various fixes to CMakeLists.txt [Lowman] +- Add checks on len in gzread() and gzwrite() +- Add error message for no more room for gzungetc() +- Remove zlib version check in gzwrite() +- Defer compression of gzprintf() result until need to +- Use snprintf() in gzdopen() if available +- Remove USE_MMAP configuration determination (only used by minigzip) +- Remove examples/pigz.c (available separately) +- Update examples/gun.c to 1.6 + +Changes in 1.2.3.5 (8 Jan 2010) +- Add space after #if in zutil.h for some compilers +- Fix relatively harmless bug in deflate_fast() [Exarevsky] +- Fix same problem in deflate_slow() +- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] +- Add deflate_rle() for faster Z_RLE strategy run-length encoding +- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding +- Change name of "write" variable in inffast.c to avoid library collisions +- Fix premature EOF from gzread() in gzio.c [Brown] +- Use zlib header window size if windowBits is 0 in inflateInit2() +- Remove compressBound() call in deflate.c to avoid linking compress.o +- Replace use of errno in gz* with functions, support WinCE [Alves] +- Provide alternative to perror() in minigzip.c for WinCE [Alves] +- Don't use _vsnprintf on later versions of MSVC [Lowman] +- Add CMake build script and input file [Lowman] +- Update contrib/minizip to 1.1 [Svensson, Vollant] +- Moved nintendods directory from contrib to . +- Replace gzio.c with a new set of routines with the same functionality +- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above +- Update contrib/minizip to 1.1b +- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h + +Changes in 1.2.3.4 (21 Dec 2009) +- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility +- Update comments in configure and Makefile.in for default --shared +- Fix test -z's in configure [Marquess] +- Build examplesh and minigzipsh when not testing +- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h +- Import LDFLAGS from the environment in configure +- Fix configure to populate SFLAGS with discovered CFLAGS options +- Adapt make_vms.com to the new Makefile.in [Zinser] +- Add zlib2ansi script for C++ compilation [Marquess] +- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) +- Add AMD64 assembler code for longest match to contrib [Teterin] +- Include options from $SFLAGS when doing $LDSHARED +- Simplify 64-bit file support by introducing z_off64_t type +- Make shared object files in objs directory to work around old Sun cc +- Use only three-part version number for Darwin shared compiles +- Add rc option to ar in Makefile.in for when ./configure not run +- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* +- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile +- Protect against _FILE_OFFSET_BITS being defined when compiling zlib +- Rename Makefile.in targets allstatic to static and allshared to shared +- Fix static and shared Makefile.in targets to be independent +- Correct error return bug in gz_open() by setting state [Brown] +- Put spaces before ;;'s in configure for better sh compatibility +- Add pigz.c (parallel implementation of gzip) to examples/ +- Correct constant in crc32.c to UL [Leventhal] +- Reject negative lengths in crc32_combine() +- Add inflateReset2() function to work like inflateEnd()/inflateInit2() +- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] +- Correct typo in doc/algorithm.txt [Janik] +- Fix bug in adler32_combine() [Zhu] +- Catch missing-end-of-block-code error in all inflates and in puff + Assures that random input to inflate eventually results in an error +- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ +- Update ENOUGH and its usage to reflect discovered bounds +- Fix gzerror() error report on empty input file [Brown] +- Add ush casts in trees.c to avoid pedantic runtime errors +- Fix typo in zlib.h uncompress() description [Reiss] +- Correct inflate() comments with regard to automatic header detection +- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) +- Put new version of gzlog (2.0) in examples with interruption recovery +- Add puff compile option to permit invalid distance-too-far streams +- Add puff TEST command options, ability to read piped input +- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but + _LARGEFILE64_SOURCE not defined +- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart +- Fix deflateSetDictionary() to use all 32K for output consistency +- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) +- Clear bytes after deflate lookahead to avoid use of uninitialized data +- Change a limit in inftrees.c to be more transparent to Coverity Prevent +- Update win32/zlib.def with exported symbols from zlib.h +- Correct spelling errors in zlib.h [Willem, Sobrado] +- Allow Z_BLOCK for deflate() to force a new block +- Allow negative bits in inflatePrime() to delete existing bit buffer +- Add Z_TREES flush option to inflate() to return at end of trees +- Add inflateMark() to return current state information for random access +- Add Makefile for NintendoDS to contrib [Costa] +- Add -w in configure compile tests to avoid spurious warnings [Beucler] +- Fix typos in zlib.h comments for deflateSetDictionary() +- Fix EOF detection in transparent gzread() [Maier] + +Changes in 1.2.3.3 (2 October 2006) +- Make --shared the default for configure, add a --static option +- Add compile option to permit invalid distance-too-far streams +- Add inflateUndermine() function which is required to enable above +- Remove use of "this" variable name for C++ compatibility [Marquess] +- Add testing of shared library in make test, if shared library built +- Use ftello() and fseeko() if available instead of ftell() and fseek() +- Provide two versions of all functions that use the z_off_t type for + binary compatibility -- a normal version and a 64-bit offset version, + per the Large File Support Extension when _LARGEFILE64_SOURCE is + defined; use the 64-bit versions by default when _FILE_OFFSET_BITS + is defined to be 64 +- Add a --uname= option to configure to perhaps help with cross-compiling + +Changes in 1.2.3.2 (3 September 2006) +- Turn off silly Borland warnings [Hay] +- Use off64_t and define _LARGEFILE64_SOURCE when present +- Fix missing dependency on inffixed.h in Makefile.in +- Rig configure --shared to build both shared and static [Teredesai, Truta] +- Remove zconf.in.h and instead create a new zlibdefs.h file +- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] +- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] + +Changes in 1.2.3.1 (16 August 2006) +- Add watcom directory with OpenWatcom make files [Daniel] +- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] +- Update make_vms.com [Zinser] +- Use -fPIC for shared build in configure [Teredesai, Nicholson] +- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] +- Use fdopen() (not _fdopen()) for Interix in zutil.h [BŠck] +- Add some FAQ entries about the contrib directory +- Update the MVS question in the FAQ +- Avoid extraneous reads after EOF in gzio.c [Brown] +- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] +- Add comments to zlib.h about gzerror() usage [Brown] +- Set extra flags in gzip header in gzopen() like deflate() does +- Make configure options more compatible with double-dash conventions + [Weigelt] +- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] +- Fix uninstall target in Makefile.in [Truta] +- Add pkgconfig support [Weigelt] +- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] +- Replace set_data_type() with a more accurate detect_data_type() in + trees.c, according to the txtvsbin.txt document [Truta] +- Swap the order of #include and #include "zlib.h" in + gzio.c, example.c and minigzip.c [Truta] +- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, + Truta] (where?) +- Fix target "clean" from win32/Makefile.bor [Truta] +- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] +- Update zlib www home address in win32/DLL_FAQ.txt [Truta] +- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] +- Enable browse info in the "Debug" and "ASM Debug" configurations in + the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] +- Add pkgconfig support [Weigelt] +- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, + for use in win32/zlib1.rc [Polushin, Rowe, Truta] +- Add a document that explains the new text detection scheme to + doc/txtvsbin.txt [Truta] +- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] +- Move algorithm.txt into doc/ [Truta] +- Synchronize FAQ with website +- Fix compressBound(), was low for some pathological cases [Fearnley] +- Take into account wrapper variations in deflateBound() +- Set examples/zpipe.c input and output to binary mode for Windows +- Update examples/zlib_how.html with new zpipe.c (also web site) +- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems + that gcc became pickier in 4.0) +- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain + un-versioned, the patch adds versioning only for symbols introduced in + zlib-1.2.0 or later. It also declares as local those symbols which are + not designed to be exported." [Levin] +- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure +- Do not initialize global static by default in trees.c, add a response + NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] +- Don't use strerror() in gzio.c under WinCE [Yakimov] +- Don't use errno.h in zutil.h under WinCE [Yakimov] +- Move arguments for AR to its usage to allow replacing ar [Marot] +- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] +- Improve inflateInit() and inflateInit2() documentation +- Fix structure size comment in inflate.h +- Change configure help option from --h* to --help [Santos] + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Add zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Løvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/libz/FAQ b/libz/FAQ new file mode 100644 index 000000000..99b7cf92e --- /dev/null +++ b/libz/FAQ @@ -0,0 +1,368 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://zlib.net/ which may have more recent information. +The lastest zlib FAQ is at http://zlib.net/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. See the + file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the + precompiled DLL are found in the zlib web site at http://zlib.net/ . + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://marknelson.us/1997/01/01/zlib-engine/ + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress(), the length of the compressed + buffer is equal to the available size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not zero. + When setting the parameter flush equal to Z_FINISH, also make sure that + avail_out is big enough to allow processing all pending input. Note that a + Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be + made with more input or output space. A Z_BUF_ERROR may in fact be + unavoidable depending on how the functions are used, since it is not + possible to tell whether or not there is more output pending when + strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a + heavily annotated example. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h . Examples of zlib usage are in the files test/example.c + and test/minigzip.c, with more in examples/ . + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple package. + zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of zlib. + Please try to reproduce the problem with a small program and send the + corresponding source to us at zlib@gzip.org . Do not send multi-megabyte + data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + By default a shared (and a static) library is built for Unix. So: + + make distclean + ./configure + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to + it. You can check the version at the top of zlib.h or with the + ZLIB_VERSION symbol defined in zlib.h . + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See http://www.pdflib.com/ . To modify PDF forms, see + http://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip formats + use the same compressed data format internally, but have different headers + and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about a + single file, such as the name and last modification date. The zlib format + on the other hand was designed for in-memory and communication channel + applications, and has a much more compact header and trailer and uses a + faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode the + gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's *Init* functions + allow for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + Yes. It has been tested on 64-bit machines, and has no dependence on any + data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format than + does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically use + Z_FULL_FLUSH, carefully write all the pending data at those points, and + keep an index of those locations, then you can start decompression at those + points. You have to be careful to not use Z_FULL_FLUSH too often, since it + can significantly degrade compression. Alternatively, you can scan a + deflate stream once to generate an index, and then use that index for + random access. See examples/zran.c . + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + It has in the past, but we have not heard of any recent evidence. There + were working ports of zlib 1.1.4 to MVS, but those links no longer work. + If you know of recent, successful applications of zlib on these operating + systems, please let us know. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at to + understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + http://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit only + if the compiler's "long" type is 32 bits. If the compiler's "long" type is + 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib is + compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of an 8K string space (or other value as set by + gzbuffer()), other than the caller of gzprintf() assuring that the output + will not exceed 8K. On the other hand, if zlib is compiled to use + snprintf() or vsnprintf(), which should normally be the case, then there is + no vulnerability. The ./configure script will display warnings if an + insecure variation of sprintf() will be used by gzprintf(). Also the + zlibCompileFlags() function will return information on what variant of + sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + http://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability, and versions + 1.2.1 and 1.2.2 were subject to an access exception when decompressing + invalid compressed data. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: http://zlib.net/ . + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly as well as contradicted each other. So now, we simply + make sure that the code always works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of deflate + is not affected. This only started showing up recently since zlib 1.2.x + uses malloc() by default for allocations, whereas earlier versions used + calloc(), which zeros out the allocated memory. Even though the code was + correct, versions 1.2.4 and later was changed to not stimulate these + checkers. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very + weak and can be broken with freely available programs. To get strong + encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib + compression. For PKZIP compatible "encryption", look at + http://www.info-zip.org/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion with + the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specification in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. In + any case, the compression improvements are so modest compared to other more + modern approaches, that it's not worth the effort to implement. + +41. I'm having a problem with the zip functions in zlib, can you help? + + There are no zip functions in zlib. You are probably using minizip by + Giles Vollant, which is found in the contrib directory of zlib. It is not + part of zlib. In fact none of the stuff in contrib is part of zlib. The + files in there are not supported by the zlib authors. You need to contact + the authors of the respective contribution for help. + +42. The match.asm code in contrib is under the GNU General Public License. + Since it's part of zlib, doesn't that mean that all of zlib falls under the + GNU GPL? + + No. The files in contrib are not part of zlib. They were contributed by + other authors and are provided as a convenience to the user within the zlib + distribution. Each item in contrib has its own license. + +43. Is zlib subject to export controls? What is its ECCN? + + zlib is not subject to export controls, and so is classified as EAR99. + +44. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/libz/INDEX b/libz/INDEX new file mode 100644 index 000000000..2ba064120 --- /dev/null +++ b/libz/INDEX @@ -0,0 +1,68 @@ +CMakeLists.txt cmake build file +ChangeLog history of changes +FAQ Frequently Asked Questions about zlib +INDEX this file +Makefile dummy Makefile that tells you to ./configure +Makefile.in template for Unix Makefile +README guess what +configure configure script for Unix +make_vms.com makefile for VMS +test/example.c zlib usages examples for build testing +test/minigzip.c minimal gzip-like functionality for build testing +test/infcover.c inf*.c code coverage for build coverage testing +treebuild.xml XML description of source file dependencies +zconf.h.cmakein zconf.h template for cmake +zconf.h.in zconf.h template for configure +zlib.3 Man page for zlib +zlib.3.pdf Man page in PDF format +zlib.map Linux symbol information +zlib.pc.in Template for pkg-config descriptor +zlib.pc.cmakein zlib.pc template for cmake +zlib2ansi perl script to convert source files for C++ compilation + +amiga/ makefiles for Amiga SAS C +as400/ makefiles for AS/400 +doc/ documentation for formats and algorithms +msdos/ makefiles for MSDOS +nintendods/ makefile for Nintendo DS +old/ makefiles for various architectures and zlib documentation + files that have not yet been updated for zlib 1.2.x +qnx/ makefiles for QNX +watcom/ makefiles for OpenWatcom +win32/ makefiles for Windows + + zlib public header files (required for library use): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +crc32.h +deflate.c +deflate.h +gzclose.c +gzguts.h +gzlib.c +gzread.c +gzwrite.c +infback.c +inffast.c +inffast.h +inffixed.h +inflate.c +inflate.h +inftrees.c +inftrees.h +trees.c +trees.h +uncompr.c +zutil.c +zutil.h + + source files for sample programs +See examples/README.examples + + unsupported contributions by third parties +See contrib/README.contrib diff --git a/libz/Makefile.in b/libz/Makefile.in new file mode 100644 index 000000000..c61aa3008 --- /dev/null +++ b/libz/Makefile.in @@ -0,0 +1,288 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static + +# To use the asm code, type: +# cp contrib/asm?86/match.S ./match.S +# make LOC=-DASMV OBJA=match.o + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +SFLAGS=-O +LDFLAGS= +TEST_LDFLAGS=-L. libz.a +LDSHARED=$(CC) +CPP=$(CC) -E + +STATICLIB=libz.a +SHAREDLIB=libz.so +SHAREDLIBV=libz.so.1.2.8 +SHAREDLIBM=libz.so.1 +LIBS=$(STATICLIB) $(SHAREDLIBV) + +AR=ar +ARFLAGS=rc +RANLIB=ranlib +LDCONFIG=ldconfig +LDSHAREDLIBC=-lc +TAR=tar +SHELL=/bin/sh +EXE= + +prefix = /usr/local +exec_prefix = ${prefix} +libdir = ${exec_prefix}/lib +sharedlibdir = ${libdir} +includedir = ${prefix}/include +mandir = ${prefix}/share/man +man3dir = ${mandir}/man3 +pkgconfigdir = ${libdir}/pkgconfig + +OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o +OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o +OBJC = $(OBJZ) $(OBJG) + +PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo +PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo +PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) + +# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo +OBJA = +PIC_OBJA = + +OBJS = $(OBJC) $(OBJA) + +PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA) + +all: static shared + +static: example$(EXE) minigzip$(EXE) + +shared: examplesh$(EXE) minigzipsh$(EXE) + +all64: example64$(EXE) minigzip64$(EXE) + +check: test + +test: all teststatic testshared + +teststatic: static + @TMPST=tmpst_$$; \ + if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; false; \ + fi; \ + rm -f $$TMPST + +testshared: shared + @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ + DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ + SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ + TMPSH=tmpsh_$$; \ + if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \ + echo ' *** zlib shared test OK ***'; \ + else \ + echo ' *** zlib shared test FAILED ***'; false; \ + fi; \ + rm -f $$TMPSH + +test64: all64 + @TMP64=tmp64_$$; \ + if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \ + echo ' *** zlib 64-bit test OK ***'; \ + else \ + echo ' *** zlib 64-bit test FAILED ***'; false; \ + fi; \ + rm -f $$TMP64 + +infcover.o: test/infcover.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/infcover.c + +infcover: infcover.o libz.a + $(CC) $(CFLAGS) -o $@ infcover.o libz.a + +cover: infcover + rm -f *.gcda + ./infcover + gcov inf*.c + +libz.a: $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +match.o: match.S + $(CPP) match.S > _match.s + $(CC) -c _match.s + mv _match.o match.o + rm -f _match.s + +match.lo: match.S + $(CPP) match.S > _match.s + $(CC) -c -fPIC _match.s + mv _match.o match.lo + rm -f _match.s + +example.o: test/example.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/example.c + +minigzip.o: test/minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c + +example64.o: test/example.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/example.c + +minigzip64.o: test/minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/minigzip.c + +.SUFFIXES: .lo + +.c.lo: + -@mkdir objs 2>/dev/null || test -d objs + $(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $< + -@mv objs/$*.o $@ + +placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a + $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) + rm -f $(SHAREDLIB) $(SHAREDLIBM) + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIBM) + -@rmdir objs + +example$(EXE): example.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) + +minigzip$(EXE): minigzip.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) + +examplesh$(EXE): example.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV) + +minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) + $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV) + +example64$(EXE): example64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) + +minigzip64$(EXE): minigzip64.o $(STATICLIB) + $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS) + +install-libs: $(LIBS) + -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi + -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi + -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi + -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi + -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + cp $(STATICLIB) $(DESTDIR)$(libdir) + chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) + -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1 + -@if test -n "$(SHAREDLIBV)"; then \ + cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \ + echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \ + chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ + echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \ + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \ + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ + ($(LDCONFIG) || true) >/dev/null 2>&1; \ + fi + cp zlib.3 $(DESTDIR)$(man3dir) + chmod 644 $(DESTDIR)$(man3dir)/zlib.3 + cp zlib.pc $(DESTDIR)$(pkgconfigdir) + chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc +# The ranlib in install is needed on NeXTSTEP which checks file times +# ldconfig is for Linux + +install: install-libs + -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi + cp zlib.h zconf.h $(DESTDIR)$(includedir) + chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h + +uninstall: + cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h + cd $(DESTDIR)$(libdir) && rm -f libz.a; \ + if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ + rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ + fi + cd $(DESTDIR)$(man3dir) && rm -f zlib.3 + cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc + +docs: zlib.3.pdf + +zlib.3.pdf: zlib.3 + groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf + +zconf.h.cmakein: zconf.h.in + -@ TEMPFILE=zconfh_$$; \ + echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\ + sed -f $$TEMPFILE zconf.h.in > zconf.h.cmakein &&\ + touch -r zconf.h.in zconf.h.cmakein &&\ + rm $$TEMPFILE + +zconf: zconf.h.in + cp -p zconf.h.in zconf.h + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ \ + example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ + example64$(EXE) minigzip64$(EXE) \ + infcover \ + libz.* foo.gz so_locations \ + _match.s maketree contrib/infback9/*.o + rm -rf objs + rm -f *.gcda *.gcno *.gcov + rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov + +maintainer-clean: distclean +distclean: clean zconf zconf.h.cmakein docs + rm -f Makefile zlib.pc configure.log + -@rm -f .DS_Store + -@printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile + -@printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile + -@touch -r Makefile.in Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o zutil.o: zutil.h zlib.h zconf.h +gzclose.o gzlib.o gzread.o gzwrite.o: zlib.h zconf.h gzguts.h +compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h +crc32.o: zutil.h zlib.h zconf.h crc32.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +infback.o inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h + +adler32.lo zutil.lo: zutil.h zlib.h zconf.h +gzclose.lo gzlib.lo gzread.lo gzwrite.lo: zlib.h zconf.h gzguts.h +compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h +crc32.lo: zutil.h zlib.h zconf.h crc32.h +deflate.lo: deflate.h zutil.h zlib.h zconf.h +infback.lo inflate.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h +inffast.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.lo: zutil.h zlib.h zconf.h inftrees.h +trees.lo: deflate.h zutil.h zlib.h zconf.h trees.h diff --git a/libz/NMAP_MODIFICATIONS b/libz/NMAP_MODIFICATIONS new file mode 100644 index 000000000..a5a97e6a1 --- /dev/null +++ b/libz/NMAP_MODIFICATIONS @@ -0,0 +1,13 @@ +diff --git a/libz/configure b/libz/configure +index b77a8a8..9e8c8ff 100755 +--- a/libz/configure ++++ b/libz/configure +@@ -124,7 +124,8 @@ case "$1" in + *) + echo "unknown option: $1" | tee -a configure.log + echo "$0 --help for help" | tee -a configure.log +- leave 1;; ++ # leave 1;; # Hack for nmap compilation ++ shift;; + esac + done \ No newline at end of file diff --git a/libz/README b/libz/README new file mode 100644 index 000000000..5ca9d127e --- /dev/null +++ b/libz/README @@ -0,0 +1,115 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.8 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and +rfc1952 (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file test/example.c which also tests that +the library is working correctly. Another example is given in the file +test/minigzip.c. The compression library itself is composed of all source +files in the root directory. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile.in. In short "./configure; make test", and if that goes +well, "make install" should work for most flavors of Unix. For Windows, use +one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available at +http://marknelson.us/1997/01/01/zlib-engine/ . + +The changes made in version 1.2.8 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory contrib/ . + +zlib is available in Java using the java.util.zip package, documented at +http://java.sun.com/developer/technicalArticles/Programming/compression/ . + +A Perl interface to zlib written by Paul Marquess is available +at CPAN (Comprehensive Perl Archive Network) sites, including +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://docs.python.org/library/zlib.html . + +zlib is built into tcl: http://wiki.tcl.tk/4610 . + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS or BEOS. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate and + zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; they + are too numerous to cite here. + +Copyright notice: + + (C) 1995-2013 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/libz/VERSION.1.2.8 b/libz/VERSION.1.2.8 new file mode 100644 index 000000000..e69de29bb diff --git a/libz/adler32.c b/libz/adler32.c new file mode 100644 index 000000000..a868f073d --- /dev/null +++ b/libz/adler32.c @@ -0,0 +1,179 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); + +#define BASE 65521 /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware -- + try it both ways to see which is faster */ +#ifdef NO_DIVIDE +/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 + (thank you to John Reiser for pointing this out) */ +# define CHOP(a) \ + do { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +# define MOD28(a) \ + do { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD(a) \ + do { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +# define MOD63(a) \ + do { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD28(a) a %= BASE +# define MOD63(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; + + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/libz/amiga/Makefile.pup b/libz/amiga/Makefile.pup new file mode 100644 index 000000000..8940c120f --- /dev/null +++ b/libz/amiga/Makefile.pup @@ -0,0 +1,69 @@ +# Amiga powerUP (TM) Makefile +# makefile for libpng and SAS C V6.58/7.00 PPC compiler +# Copyright (C) 1998 by Andreas R. Kleinert + +LIBNAME = libzip.a + +CC = scppc +CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \ + OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER +AR = ppc-amigaos-ar cr +RANLIB = ppc-amigaos-ranlib +LD = ppc-amigaos-ld -r +LDFLAGS = -o +LDLIBS = LIB:scppc.a LIB:end.o +RM = delete quiet + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example minigzip + +check: test +test: all + example + echo hello world | minigzip | minigzip -d + +$(LIBNAME): $(OBJS) + $(AR) $@ $(OBJS) + -$(RANLIB) $@ + +example: example.o $(LIBNAME) + $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS) + +minigzip: minigzip.o $(LIBNAME) + $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS) + +mostlyclean: clean +clean: + $(RM) *.o example minigzip $(LIBNAME) foo.gz + +zip: + zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \ + descrip.mms *.[ch] + +tgz: + cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \ + zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: crc32.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzclose.o: zlib.h zconf.h gzguts.h +gzlib.o: zlib.h zconf.h gzguts.h +gzread.o: zlib.h zconf.h gzguts.h +gzwrite.o: zlib.h zconf.h gzguts.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/libz/amiga/Makefile.sas b/libz/amiga/Makefile.sas new file mode 100644 index 000000000..749e29152 --- /dev/null +++ b/libz/amiga/Makefile.sas @@ -0,0 +1,68 @@ +# SMakefile for zlib +# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly +# Osma Ahvenlampi +# Amiga, SAS/C 6.56 & Smake + +CC=sc +CFLAGS=OPT +#CFLAGS=OPT CPU=68030 +#CFLAGS=DEBUG=LINE +LDFLAGS=LIB z.lib + +SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \ + NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \ + DEF=POSTINC + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: SCOPTIONS example minigzip + +check: test +test: all + example + echo hello world | minigzip | minigzip -d + +install: z.lib + copy clone zlib.h zconf.h INCLUDE: + copy clone z.lib LIB: + +z.lib: $(OBJS) + oml z.lib r $(OBJS) + +example: example.o z.lib + $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS) + +minigzip: minigzip.o z.lib + $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS) + +mostlyclean: clean +clean: + -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS + +SCOPTIONS: Makefile.sas + copy to $@ 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; +} diff --git a/libz/configure b/libz/configure new file mode 100644 index 000000000..9e8c8ffca --- /dev/null +++ b/libz/configure @@ -0,0 +1,832 @@ +#!/bin/sh +# configure script for zlib. +# +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static +# +# To impose specific compiler or flags or install directory, use for example: +# prefix=$HOME CC=cc CFLAGS="-O4" ./configure +# or for csh/tcsh users: +# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) + +# Incorrect settings of CC or CFLAGS may prevent creating a shared library. +# If you have problems, try without defining CC and CFLAGS before reporting +# an error. + +# start off configure.log +echo -------------------- >> configure.log +echo $0 $* >> configure.log +date >> configure.log + +# set command prefix for cross-compilation +if [ -n "${CHOST}" ]; then + uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`" + CROSS_PREFIX="${CHOST}-" +fi + +# destination name for static library +STATICLIB=libz.a + +# extract zlib version numbers from zlib.h +VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` +VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < zlib.h` +VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h` +VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h` + +# establish commands for library building +if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then + AR=${AR-"${CROSS_PREFIX}ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +else + AR=${AR-"ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +fi +ARFLAGS=${ARFLAGS-"rc"} +if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then + RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} + test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log +else + RANLIB=${RANLIB-"ranlib"} +fi +if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then + NM=${NM-"${CROSS_PREFIX}nm"} + test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log +else + NM=${NM-"nm"} +fi + +# set defaults before processing command line options +LDCONFIG=${LDCONFIG-"ldconfig"} +LDSHAREDLIBC="${LDSHAREDLIBC--lc}" +ARCHS= +prefix=${prefix-/usr/local} +exec_prefix=${exec_prefix-'${prefix}'} +libdir=${libdir-'${exec_prefix}/lib'} +sharedlibdir=${sharedlibdir-'${libdir}'} +includedir=${includedir-'${prefix}/include'} +mandir=${mandir-'${prefix}/share/man'} +shared_ext='.so' +shared=1 +solo=0 +cover=0 +zprefix=0 +zconst=0 +build64=0 +gcc=0 +old_cc="$CC" +old_cflags="$CFLAGS" +OBJC='$(OBJZ) $(OBJG)' +PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)' + +# leave this script, optionally in a bad way +leave() +{ + if test "$*" != "0"; then + echo "** $0 aborting." | tee -a configure.log + fi + rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version + echo -------------------- >> configure.log + echo >> configure.log + echo >> configure.log + exit $1 +} + +# process command line options +while test $# -ge 1 +do +case "$1" in + -h* | --help) + echo 'usage:' | tee -a configure.log + echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log + echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log + echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log + exit 0 ;; + -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; + -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;; + --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;; + -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;; + -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;; + -p* | --prefix) prefix="$2"; shift; shift ;; + -e* | --eprefix) exec_prefix="$2"; shift; shift ;; + -l* | --libdir) libdir="$2"; shift; shift ;; + -i* | --includedir) includedir="$2"; shift; shift ;; + -s* | --shared | --enable-shared) shared=1; shift ;; + -t | --static) shared=0; shift ;; + --solo) solo=1; shift ;; + --cover) cover=1; shift ;; + -z* | --zprefix) zprefix=1; shift ;; + -6* | --64) build64=1; shift ;; + -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;; + --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; + --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; + -c* | --const) zconst=1; shift ;; + *) + echo "unknown option: $1" | tee -a configure.log + echo "$0 --help for help" | tee -a configure.log + # leave 1;; # Hack for nmap compilation + shift;; + esac +done + +# temporary file name +test=ztest$$ + +# put arguments in log, also put test file in log if used in arguments +show() +{ + case "$*" in + *$test.c*) + echo === $test.c === >> configure.log + cat $test.c >> configure.log + echo === >> configure.log;; + esac + echo $* >> configure.log +} + +# check for gcc vs. cc and set compile and link flags based on the system identified by uname +cat > $test.c <&1` in + *gcc*) gcc=1 ;; +esac + +show $cc -c $test.c +if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then + echo ... using gcc >> configure.log + CC="$cc" + CFLAGS="${CFLAGS--O3} ${ARCHS}" + SFLAGS="${CFLAGS--O3} -fPIC" + LDFLAGS="${LDFLAGS} ${ARCHS}" + if test $build64 -eq 1; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + fi + if test "${ZLIBGCCWARN}" = "YES"; then + if test "$zconst" -eq 1; then + CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST" + else + CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" + fi + fi + if test -z "$uname"; then + uname=`(uname -s || echo unknown) 2>/dev/null` + fi + case "$uname" in + Linux* | linux* | GNU | GNU/* | solaris*) + LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;; + *BSD | *bsd* | DragonFly) + LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} + LDCONFIG="ldconfig -m" ;; + CYGWIN* | Cygwin* | cygwin* | OS/2*) + EXE='.exe' ;; + MINGW* | mingw*) +# temporary bypass + rm -f $test.[co] $test $test$shared_ext + echo "Please use win32/Makefile.gcc instead." | tee -a configure.log + leave 1 + LDSHARED=${LDSHARED-"$cc -shared"} + LDSHAREDLIBC="" + EXE='.exe' ;; + QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 + # (alain.bonnefoy@icbt.com) + LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;; + HP-UX*) + LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} + case `(uname -m || echo unknown) 2>/dev/null` in + ia64) + shared_ext='.so' + SHAREDLIB='libz.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='libz.sl' ;; + esac ;; + Darwin* | darwin*) + shared_ext='.dylib' + SHAREDLIB=libz$shared_ext + SHAREDLIBV=libz.$VER$shared_ext + SHAREDLIBM=libz.$VER1$shared_ext + LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} + if libtool -V 2>&1 | grep Apple > /dev/null; then + AR="libtool" + else + AR="/usr/bin/libtool" + fi + ARFLAGS="-o" ;; + *) LDSHARED=${LDSHARED-"$cc -shared"} ;; + esac +else + # find system name and corresponding cc options + CC=${CC-cc} + gcc=0 + echo ... using $CC >> configure.log + if test -z "$uname"; then + uname=`(uname -sr || echo unknown) 2>/dev/null` + fi + case "$uname" in + HP-UX*) SFLAGS=${CFLAGS-"-O +z"} + CFLAGS=${CFLAGS-"-O"} +# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} + LDSHARED=${LDSHARED-"ld -b"} + case `(uname -m || echo unknown) 2>/dev/null` in + ia64) + shared_ext='.so' + SHAREDLIB='libz.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='libz.sl' ;; + esac ;; + IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} + CFLAGS=${CFLAGS-"-ansi -O2"} + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; + OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDFLAGS="${LDFLAGS} -Wl,-rpath,." + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;; + OSF1*) SFLAGS=${CFLAGS-"-O -std1"} + CFLAGS=${CFLAGS-"-O -std1"} + LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; + QNX*) SFLAGS=${CFLAGS-"-4 -O"} + CFLAGS=${CFLAGS-"-4 -O"} + LDSHARED=${LDSHARED-"cc"} + RANLIB=${RANLIB-"true"} + AR="cc" + ARFLAGS="-A" ;; + SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} + CFLAGS=${CFLAGS-"-O3"} + LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;; + SunOS\ 5* | solaris*) + LDSHARED=${LDSHARED-"cc -G -h libz$shared_ext.$VER1"} + SFLAGS=${CFLAGS-"-fast -KPIC"} + CFLAGS=${CFLAGS-"-fast"} + if test $build64 -eq 1; then + # old versions of SunPRO/Workshop/Studio don't support -m64, + # but newer ones do. Check for it. + flag64=`$CC -flags | egrep -- '^-m64'` + if test x"$flag64" != x"" ; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + else + case `(uname -m || echo unknown) 2>/dev/null` in + i86*) + SFLAGS="$SFLAGS -xarch=amd64" + CFLAGS="$CFLAGS -xarch=amd64" ;; + *) + SFLAGS="$SFLAGS -xarch=v9" + CFLAGS="$CFLAGS -xarch=v9" ;; + esac + fi + fi + ;; + SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} + CFLAGS=${CFLAGS-"-O2"} + LDSHARED=${LDSHARED-"ld"} ;; + SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} + CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"} + LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;; + UNIX_System_V\ 4.2.0) + SFLAGS=${CFLAGS-"-KPIC -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"} ;; + UNIX_SV\ 4.2MP) + SFLAGS=${CFLAGS-"-Kconform_pic -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"} ;; + OpenUNIX\ 5) + SFLAGS=${CFLAGS-"-KPIC -O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -G"} ;; + AIX*) # Courtesy of dbakker@arrayasolutions.com + SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + LDSHARED=${LDSHARED-"xlc -G"} ;; + # send working options for other systems to zlib@gzip.org + *) SFLAGS=${CFLAGS-"-O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc -shared"} ;; + esac +fi + +# destination names for shared library if not defined above +SHAREDLIB=${SHAREDLIB-"libz$shared_ext"} +SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"} +SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} + +echo >> configure.log + +# define functions for testing compiler and library characteristics and logging the results + +cat > $test.c </dev/null; then + try() + { + show $* + test "`( $* ) 2>&1 | tee -a configure.log`" = "" + } + echo - using any output from compiler to indicate an error >> configure.log +else +try() +{ + show $* + ( $* ) >> configure.log 2>&1 + ret=$? + if test $ret -ne 0; then + echo "(exit code "$ret")" >> configure.log + fi + return $ret +} +fi + +tryboth() +{ + show $* + got=`( $* ) 2>&1` + ret=$? + printf %s "$got" >> configure.log + if test $ret -ne 0; then + return $ret + fi + test "$got" = "" +} + +cat > $test.c << EOF +int foo() { return 0; } +EOF +echo "Checking for obsessive-compulsive compiler options..." >> configure.log +if try $CC -c $CFLAGS $test.c; then + : +else + echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log + leave 1 +fi + +echo >> configure.log + +# see if shared library build supported +cat > $test.c <> configure.log + show "$NM $test.o | grep _hello" + if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then + CPP="$CPP -DNO_UNDERLINE" + echo Checking for underline in external names... No. | tee -a configure.log + else + echo Checking for underline in external names... Yes. | tee -a configure.log + fi ;; +esac + +echo >> configure.log + +# check for large file support, and if none, check for fseeko() +cat > $test.c < +off64_t dummy = 0; +EOF +if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then + CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" + SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" + ALL="${ALL} all64" + TEST="${TEST} test64" + echo "Checking for off64_t... Yes." | tee -a configure.log + echo "Checking for fseeko... Yes." | tee -a configure.log +else + echo "Checking for off64_t... No." | tee -a configure.log + echo >> configure.log + cat > $test.c < +int main(void) { + fseeko(NULL, 0, 0); + return 0; +} +EOF + if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for fseeko... Yes." | tee -a configure.log + else + CFLAGS="${CFLAGS} -DNO_FSEEKO" + SFLAGS="${SFLAGS} -DNO_FSEEKO" + echo "Checking for fseeko... No." | tee -a configure.log + fi +fi + +echo >> configure.log + +# check for strerror() for use by gz* functions +cat > $test.c < +#include +int main() { return strlen(strerror(errno)); } +EOF +if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for strerror... Yes." | tee -a configure.log +else + CFLAGS="${CFLAGS} -DNO_STRERROR" + SFLAGS="${SFLAGS} -DNO_STRERROR" + echo "Checking for strerror... No." | tee -a configure.log +fi + +# copy clean zconf.h for subsequent edits +cp -p zconf.h.in zconf.h + +echo >> configure.log + +# check for unistd.h and save result in zconf.h +cat > $test.c < +int main() { return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo "Checking for unistd.h... Yes." | tee -a configure.log +else + echo "Checking for unistd.h... No." | tee -a configure.log +fi + +echo >> configure.log + +# check for stdarg.h and save result in zconf.h +cat > $test.c < +int main() { return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo "Checking for stdarg.h... Yes." | tee -a configure.log +else + echo "Checking for stdarg.h... No." | tee -a configure.log +fi + +# if the z_ prefix was requested, save that in zconf.h +if test $zprefix -eq 1; then + sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h + mv zconf.temp.h zconf.h + echo >> configure.log + echo "Using z_ prefix on all symbols." | tee -a configure.log +fi + +# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists +if test $solo -eq 1; then + sed '/#define ZCONF_H/a\ +#define Z_SOLO + +' < zconf.h > zconf.temp.h + mv zconf.temp.h zconf.h +OBJC='$(OBJZ)' +PIC_OBJC='$(PIC_OBJZ)' +fi + +# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X +if test $cover -eq 1; then + CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage" + if test -n "$GCC_CLASSIC"; then + CC=$GCC_CLASSIC + fi +fi + +echo >> configure.log + +# conduct a series of tests to resolve eight possible cases of using "vs" or "s" printf functions +# (using stdarg or not), with or without "n" (proving size of buffer), and with or without a +# return value. The most secure result is vsnprintf() with a return value. snprintf() with a +# return value is secure as well, but then gzprintf() will be limited to 20 arguments. +cat > $test.c < +#include +#include "zconf.h" +int main() +{ +#ifndef STDC + choke me +#endif + return 0; +} +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log + + echo >> configure.log + cat > $test.c < +#include +int mytest(const char *fmt, ...) +{ + char buf[20]; + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return 0; +} +int main() +{ + return (mytest("Hello%d\n", 1)); +} +EOF + if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +#include +int mytest(const char *fmt, ...) +{ + int n; + char buf[20]; + va_list ap; + va_start(ap, fmt); + n = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return n; +} +int main() +{ + return (mytest("Hello%d\n", 1)); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_vsnprintf_void" + SFLAGS="$SFLAGS -DHAS_vsnprintf_void" + echo "Checking for return value of vsnprintf()... No." | tee -a configure.log + echo " WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + else + CFLAGS="$CFLAGS -DNO_vsnprintf" + SFLAGS="$SFLAGS -DNO_vsnprintf" + echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log + echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log + echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +#include +int mytest(const char *fmt, ...) +{ + int n; + char buf[20]; + va_list ap; + va_start(ap, fmt); + n = vsprintf(buf, fmt, ap); + va_end(ap); + return n; +} +int main() +{ + return (mytest("Hello%d\n", 1)); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_vsprintf_void" + SFLAGS="$SFLAGS -DHAS_vsprintf_void" + echo "Checking for return value of vsprintf()... No." | tee -a configure.log + echo " WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + fi +else + echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +int mytest() +{ + char buf[20]; + snprintf(buf, sizeof(buf), "%s", "foo"); + return 0; +} +int main() +{ + return (mytest()); +} +EOF + + if try $CC $CFLAGS -o $test $test.c; then + echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +int mytest() +{ + char buf[20]; + return snprintf(buf, sizeof(buf), "%s", "foo"); +} +int main() +{ + return (mytest()); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of snprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_snprintf_void" + SFLAGS="$SFLAGS -DHAS_snprintf_void" + echo "Checking for return value of snprintf()... No." | tee -a configure.log + echo " WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + else + CFLAGS="$CFLAGS -DNO_snprintf" + SFLAGS="$SFLAGS -DNO_snprintf" + echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log + echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log + echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + + echo >> configure.log + cat >$test.c < +int mytest() +{ + char buf[20]; + return sprintf(buf, "%s", "foo"); +} +int main() +{ + return (mytest()); +} +EOF + + if try $CC -c $CFLAGS $test.c; then + echo "Checking for return value of sprintf()... Yes." | tee -a configure.log + else + CFLAGS="$CFLAGS -DHAS_sprintf_void" + SFLAGS="$SFLAGS -DHAS_sprintf_void" + echo "Checking for return value of sprintf()... No." | tee -a configure.log + echo " WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log + echo " can build but will be open to possible string-format security" | tee -a configure.log + echo " vulnerabilities." | tee -a configure.log + fi + fi +fi + +# see if we can hide zlib internal symbols that are linked between separate source files +if test "$gcc" -eq 1; then + echo >> configure.log + cat > $test.c <> configure.log +echo ALL = $ALL >> configure.log +echo AR = $AR >> configure.log +echo ARFLAGS = $ARFLAGS >> configure.log +echo CC = $CC >> configure.log +echo CFLAGS = $CFLAGS >> configure.log +echo CPP = $CPP >> configure.log +echo EXE = $EXE >> configure.log +echo LDCONFIG = $LDCONFIG >> configure.log +echo LDFLAGS = $LDFLAGS >> configure.log +echo LDSHARED = $LDSHARED >> configure.log +echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log +echo OBJC = $OBJC >> configure.log +echo PIC_OBJC = $PIC_OBJC >> configure.log +echo RANLIB = $RANLIB >> configure.log +echo SFLAGS = $SFLAGS >> configure.log +echo SHAREDLIB = $SHAREDLIB >> configure.log +echo SHAREDLIBM = $SHAREDLIBM >> configure.log +echo SHAREDLIBV = $SHAREDLIBV >> configure.log +echo STATICLIB = $STATICLIB >> configure.log +echo TEST = $TEST >> configure.log +echo VER = $VER >> configure.log +echo Z_U4 = $Z_U4 >> configure.log +echo exec_prefix = $exec_prefix >> configure.log +echo includedir = $includedir >> configure.log +echo libdir = $libdir >> configure.log +echo mandir = $mandir >> configure.log +echo prefix = $prefix >> configure.log +echo sharedlibdir = $sharedlibdir >> configure.log +echo uname = $uname >> configure.log + +# udpate Makefile with the configure results +sed < Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^CPP *=/s#=.*#=$CPP# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^LDCONFIG *=/s#=.*#=$LDCONFIG# +/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^OBJC *=/s#=.*#= $OBJC# +/^PIC_OBJC *=/s#=.*#= $PIC_OBJC# +/^all: */s#:.*#: $ALL# +/^test: */s#:.*#: $TEST# +" > Makefile + +# create zlib.pc with the configure results +sed < zlib.pc.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^CPP *=/s#=.*#=$CPP# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +" | sed -e " +s/\@VERSION\@/$VER/g; +" > zlib.pc + +# done +leave 0 diff --git a/libz/contrib/README.contrib b/libz/contrib/README.contrib new file mode 100644 index 000000000..c66349b7c --- /dev/null +++ b/libz/contrib/README.contrib @@ -0,0 +1,78 @@ +All files under this contrib directory are UNSUPPORTED. There were +provided by users of zlib and were not tested by the authors of zlib. +Use at your own risk. Please contact the authors of the contributions +for help about these, not the zlib authors. Thanks. + + +ada/ by Dmitriy Anisimkov + Support for Ada + See http://zlib-ada.sourceforge.net/ + +amd64/ by Mikhail Teterin + asm code for AMD64 + See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393 + +asm686/ by Brian Raiter + asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax + See http://www.muppetlabs.com/~breadbox/software/assembly.html + +blast/ by Mark Adler + Decompressor for output of PKWare Data Compression Library (DCL) + +delphi/ by Cosmin Truta + Support for Delphi and C++ Builder + +dotzlib/ by Henrik Ravn + Support for Microsoft .Net and Visual C++ .Net + +gcc_gvmat64/by Gilles Vollant + GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64 + assembler to replace longest_match() and inflate_fast() + +infback9/ by Mark Adler + Unsupported diffs to infback to decode the deflate64 format + +inflate86/ by Chris Anderson + Tuned x86 gcc asm code to replace inflate_fast() + +iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + +iostream2/ by Tyge Løvset + Another C++ I/O streams interface + +iostream3/ by Ludwig Schwardt + and Kevin Ruland + Yet another C++ I/O streams interface + +masmx64/ by Gilles Vollant + x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to + replace longest_match() and inflate_fast(), also masm x86 + 64-bits translation of Chris Anderson inflate_fast() + +masmx86/ by Gilles Vollant + x86 asm code to replace longest_match() and inflate_fast(), + for Visual C++ and MASM (32 bits). + Based on Brian Raiter (asm686) and Chris Anderson (inflate86) + +minizip/ by Gilles Vollant + Mini zip and unzip based on zlib + Includes Zip64 support by Mathias Svensson + See http://www.winimage.com/zLibDll/unzip.html + +pascal/ by Bob Dellaca et al. + Support for Pascal + +puff/ by Mark Adler + Small, low memory usage inflate. Also serves to provide an + unambiguous description of the deflate format. + +testzlib/ by Gilles Vollant + Example of the use of zlib + +untgz/ by Pedro A. Aranda Gutierrez + A very simple tar.gz file extractor using zlib + +vstudio/ by Gilles Vollant + Building a minizip-enhanced zlib with Microsoft Visual Studio + Includes vc11 from kreuzerkrieg and vc12 from davispuh diff --git a/libz/contrib/ada/buffer_demo.adb b/libz/contrib/ada/buffer_demo.adb new file mode 100644 index 000000000..46b863810 --- /dev/null +++ b/libz/contrib/ada/buffer_demo.adb @@ -0,0 +1,106 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- +-- +-- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $ + +-- This demo program provided by Dr Steve Sangwine +-- +-- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer +-- of exactly the correct size is used for decompressed data, and the last +-- few bytes passed in to Zlib are checksum bytes. + +-- This program compresses a string of text, and then decompresses the +-- compressed text into a buffer of the same size as the original text. + +with Ada.Streams; use Ada.Streams; +with Ada.Text_IO; + +with ZLib; use ZLib; + +procedure Buffer_Demo is + EOL : Character renames ASCII.LF; + Text : constant String + := "Four score and seven years ago our fathers brought forth," & EOL & + "upon this continent, a new nation, conceived in liberty," & EOL & + "and dedicated to the proposition that `all men are created equal'."; + + Source : Stream_Element_Array (1 .. Text'Length); + for Source'Address use Text'Address; + +begin + Ada.Text_IO.Put (Text); + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes"); + + declare + Compressed_Data : Stream_Element_Array (1 .. Text'Length); + L : Stream_Element_Offset; + begin + Compress : declare + Compressor : Filter_Type; + I : Stream_Element_Offset; + begin + Deflate_Init (Compressor); + + -- Compress the whole of T at once. + + Translate (Compressor, Source, I, Compressed_Data, L, Finish); + pragma Assert (I = Source'Last); + + Close (Compressor); + + Ada.Text_IO.Put_Line + ("Compressed size : " + & Stream_Element_Offset'Image (L) & " bytes"); + end Compress; + + -- Now we decompress the data, passing short blocks of data to Zlib + -- (because this demonstrates the problem - the last block passed will + -- contain checksum information and there will be no output, only a + -- check inside Zlib that the checksum is correct). + + Decompress : declare + Decompressor : Filter_Type; + + Uncompressed_Data : Stream_Element_Array (1 .. Text'Length); + + Block_Size : constant := 4; + -- This makes sure that the last block contains + -- only Adler checksum data. + + P : Stream_Element_Offset := Compressed_Data'First - 1; + O : Stream_Element_Offset; + begin + Inflate_Init (Decompressor); + + loop + Translate + (Decompressor, + Compressed_Data + (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)), + P, + Uncompressed_Data + (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last), + O, + No_Flush); + + Ada.Text_IO.Put_Line + ("Total in : " & Count'Image (Total_In (Decompressor)) & + ", out : " & Count'Image (Total_Out (Decompressor))); + + exit when P = L; + end loop; + + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Decompressed text matches original text : " + & Boolean'Image (Uncompressed_Data = Source)); + end Decompress; + end; +end Buffer_Demo; diff --git a/libz/contrib/ada/mtest.adb b/libz/contrib/ada/mtest.adb new file mode 100644 index 000000000..c4dfd080f --- /dev/null +++ b/libz/contrib/ada/mtest.adb @@ -0,0 +1,156 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- +-- Continuous test for ZLib multithreading. If the test would fail +-- we should provide thread safe allocation routines for the Z_Stream. +-- +-- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $ + +with ZLib; +with Ada.Streams; +with Ada.Numerics.Discrete_Random; +with Ada.Text_IO; +with Ada.Exceptions; +with Ada.Task_Identification; + +procedure MTest is + use Ada.Streams; + use ZLib; + + Stop : Boolean := False; + + pragma Atomic (Stop); + + subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#; + + package Random_Elements is + new Ada.Numerics.Discrete_Random (Visible_Symbols); + + task type Test_Task; + + task body Test_Task is + Buffer : Stream_Element_Array (1 .. 100_000); + Gen : Random_Elements.Generator; + + Buffer_First : Stream_Element_Offset; + Compare_First : Stream_Element_Offset; + + Deflate : Filter_Type; + Inflate : Filter_Type; + + procedure Further (Item : in Stream_Element_Array); + + procedure Read_Buffer + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + + ------------- + -- Further -- + ------------- + + procedure Further (Item : in Stream_Element_Array) is + + procedure Compare (Item : in Stream_Element_Array); + + ------------- + -- Compare -- + ------------- + + procedure Compare (Item : in Stream_Element_Array) is + Next_First : Stream_Element_Offset := Compare_First + Item'Length; + begin + if Buffer (Compare_First .. Next_First - 1) /= Item then + raise Program_Error; + end if; + + Compare_First := Next_First; + end Compare; + + procedure Compare_Write is new ZLib.Write (Write => Compare); + begin + Compare_Write (Inflate, Item, No_Flush); + end Further; + + ----------------- + -- Read_Buffer -- + ----------------- + + procedure Read_Buffer + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset) + is + Buff_Diff : Stream_Element_Offset := Buffer'Last - Buffer_First; + Next_First : Stream_Element_Offset; + begin + if Item'Length <= Buff_Diff then + Last := Item'Last; + + Next_First := Buffer_First + Item'Length; + + Item := Buffer (Buffer_First .. Next_First - 1); + + Buffer_First := Next_First; + else + Last := Item'First + Buff_Diff; + Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last); + Buffer_First := Buffer'Last + 1; + end if; + end Read_Buffer; + + procedure Translate is new Generic_Translate + (Data_In => Read_Buffer, + Data_Out => Further); + + begin + Random_Elements.Reset (Gen); + + Buffer := (others => 20); + + Main : loop + for J in Buffer'Range loop + Buffer (J) := Random_Elements.Random (Gen); + + Deflate_Init (Deflate); + Inflate_Init (Inflate); + + Buffer_First := Buffer'First; + Compare_First := Buffer'First; + + Translate (Deflate); + + if Compare_First /= Buffer'Last + 1 then + raise Program_Error; + end if; + + Ada.Text_IO.Put_Line + (Ada.Task_Identification.Image + (Ada.Task_Identification.Current_Task) + & Stream_Element_Offset'Image (J) + & ZLib.Count'Image (Total_Out (Deflate))); + + Close (Deflate); + Close (Inflate); + + exit Main when Stop; + end loop; + end loop Main; + exception + when E : others => + Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E)); + Stop := True; + end Test_Task; + + Test : array (1 .. 4) of Test_Task; + + pragma Unreferenced (Test); + + Dummy : Character; + +begin + Ada.Text_IO.Get_Immediate (Dummy); + Stop := True; +end MTest; diff --git a/libz/contrib/ada/read.adb b/libz/contrib/ada/read.adb new file mode 100644 index 000000000..1f2efbfeb --- /dev/null +++ b/libz/contrib/ada/read.adb @@ -0,0 +1,156 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $ + +-- Test/demo program for the generic read interface. + +with Ada.Numerics.Discrete_Random; +with Ada.Streams; +with Ada.Text_IO; + +with ZLib; + +procedure Read is + + use Ada.Streams; + + ------------------------------------ + -- Test configuration parameters -- + ------------------------------------ + + File_Size : Stream_Element_Offset := 100_000; + + Continuous : constant Boolean := False; + -- If this constant is True, the test would be repeated again and again, + -- with increment File_Size for every iteration. + + Header : constant ZLib.Header_Type := ZLib.Default; + -- Do not use Header other than Default in ZLib versions 1.1.4 and older. + + Init_Random : constant := 8; + -- We are using the same random sequence, in case of we catch bug, + -- so we would be able to reproduce it. + + -- End -- + + Pack_Size : Stream_Element_Offset; + Offset : Stream_Element_Offset; + + Filter : ZLib.Filter_Type; + + subtype Visible_Symbols + is Stream_Element range 16#20# .. 16#7E#; + + package Random_Elements is new + Ada.Numerics.Discrete_Random (Visible_Symbols); + + Gen : Random_Elements.Generator; + Period : constant Stream_Element_Offset := 200; + -- Period constant variable for random generator not to be very random. + -- Bigger period, harder random. + + Read_Buffer : Stream_Element_Array (1 .. 2048); + Read_First : Stream_Element_Offset; + Read_Last : Stream_Element_Offset; + + procedure Reset; + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset); + -- this procedure is for generic instantiation of + -- ZLib.Read + -- reading data from the File_In. + + procedure Read is new ZLib.Read + (Read, + Read_Buffer, + Rest_First => Read_First, + Rest_Last => Read_Last); + + ---------- + -- Read -- + ---------- + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) is + begin + Last := Stream_Element_Offset'Min + (Item'Last, + Item'First + File_Size - Offset); + + for J in Item'First .. Last loop + if J < Item'First + Period then + Item (J) := Random_Elements.Random (Gen); + else + Item (J) := Item (J - Period); + end if; + + Offset := Offset + 1; + end loop; + end Read; + + ----------- + -- Reset -- + ----------- + + procedure Reset is + begin + Random_Elements.Reset (Gen, Init_Random); + Pack_Size := 0; + Offset := 1; + Read_First := Read_Buffer'Last + 1; + Read_Last := Read_Buffer'Last; + end Reset; + +begin + Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version); + + loop + for Level in ZLib.Compression_Level'Range loop + + Ada.Text_IO.Put ("Level =" + & ZLib.Compression_Level'Image (Level)); + + -- Deflate using generic instantiation. + + ZLib.Deflate_Init + (Filter, + Level, + Header => Header); + + Reset; + + Ada.Text_IO.Put + (Stream_Element_Offset'Image (File_Size) & " ->"); + + loop + declare + Buffer : Stream_Element_Array (1 .. 1024); + Last : Stream_Element_Offset; + begin + Read (Filter, Buffer, Last); + + Pack_Size := Pack_Size + Last - Buffer'First + 1; + + exit when Last < Buffer'Last; + end; + end loop; + + Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size)); + + ZLib.Close (Filter); + end loop; + + exit when not Continuous; + + File_Size := File_Size + 1; + end loop; +end Read; diff --git a/libz/contrib/ada/readme.txt b/libz/contrib/ada/readme.txt new file mode 100644 index 000000000..ce4d2cadf --- /dev/null +++ b/libz/contrib/ada/readme.txt @@ -0,0 +1,65 @@ + ZLib for Ada thick binding (ZLib.Ada) + Release 1.3 + +ZLib.Ada is a thick binding interface to the popular ZLib data +compression library, available at http://www.gzip.org/zlib/. +It provides Ada-style access to the ZLib C library. + + + Here are the main changes since ZLib.Ada 1.2: + +- Attension: ZLib.Read generic routine have a initialization requirement + for Read_Last parameter now. It is a bit incompartible with previous version, + but extends functionality, we could use new parameters Allow_Read_Some and + Flush now. + +- Added Is_Open routines to ZLib and ZLib.Streams packages. + +- Add pragma Assert to check Stream_Element is 8 bit. + +- Fix extraction to buffer with exact known decompressed size. Error reported by + Steve Sangwine. + +- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits + computers. Patch provided by Pascal Obry. + +- Add Status_Error exception definition. + +- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit. + + + How to build ZLib.Ada under GNAT + +You should have the ZLib library already build on your computer, before +building ZLib.Ada. Make the directory of ZLib.Ada sources current and +issue the command: + + gnatmake test -largs -L -lz + +Or use the GNAT project file build for GNAT 3.15 or later: + + gnatmake -Pzlib.gpr -L + + + How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2 + +1. Make a project with all *.ads and *.adb files from the distribution. +2. Build the libz.a library from the ZLib C sources. +3. Rename libz.a to z.lib. +4. Add the library z.lib to the project. +5. Add the libc.lib library from the ObjectAda distribution to the project. +6. Build the executable using test.adb as a main procedure. + + + How to use ZLib.Ada + +The source files test.adb and read.adb are small demo programs that show +the main functionality of ZLib.Ada. + +The routines from the package specifications are commented. + + +Homepage: http://zlib-ada.sourceforge.net/ +Author: Dmitriy Anisimkov + +Contributors: Pascal Obry , Steve Sangwine diff --git a/libz/contrib/ada/test.adb b/libz/contrib/ada/test.adb new file mode 100644 index 000000000..90773acfa --- /dev/null +++ b/libz/contrib/ada/test.adb @@ -0,0 +1,463 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $ + +-- The program has a few aims. +-- 1. Test ZLib.Ada95 thick binding functionality. +-- 2. Show the example of use main functionality of the ZLib.Ada95 binding. +-- 3. Build this program automatically compile all ZLib.Ada95 packages under +-- GNAT Ada95 compiler. + +with ZLib.Streams; +with Ada.Streams.Stream_IO; +with Ada.Numerics.Discrete_Random; + +with Ada.Text_IO; + +with Ada.Calendar; + +procedure Test is + + use Ada.Streams; + use Stream_IO; + + ------------------------------------ + -- Test configuration parameters -- + ------------------------------------ + + File_Size : Count := 100_000; + Continuous : constant Boolean := False; + + Header : constant ZLib.Header_Type := ZLib.Default; + -- ZLib.None; + -- ZLib.Auto; + -- ZLib.GZip; + -- Do not use Header other then Default in ZLib versions 1.1.4 + -- and older. + + Strategy : constant ZLib.Strategy_Type := ZLib.Default_Strategy; + Init_Random : constant := 10; + + -- End -- + + In_File_Name : constant String := "testzlib.in"; + -- Name of the input file + + Z_File_Name : constant String := "testzlib.zlb"; + -- Name of the compressed file. + + Out_File_Name : constant String := "testzlib.out"; + -- Name of the decompressed file. + + File_In : File_Type; + File_Out : File_Type; + File_Back : File_Type; + File_Z : ZLib.Streams.Stream_Type; + + Filter : ZLib.Filter_Type; + + Time_Stamp : Ada.Calendar.Time; + + procedure Generate_File; + -- Generate file of spetsified size with some random data. + -- The random data is repeatable, for the good compression. + + procedure Compare_Streams + (Left, Right : in out Root_Stream_Type'Class); + -- The procedure compearing data in 2 streams. + -- It is for compare data before and after compression/decompression. + + procedure Compare_Files (Left, Right : String); + -- Compare files. Based on the Compare_Streams. + + procedure Copy_Streams + (Source, Target : in out Root_Stream_Type'Class; + Buffer_Size : in Stream_Element_Offset := 1024); + -- Copying data from one stream to another. It is for test stream + -- interface of the library. + + procedure Data_In + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset); + -- this procedure is for generic instantiation of + -- ZLib.Generic_Translate. + -- reading data from the File_In. + + procedure Data_Out (Item : in Stream_Element_Array); + -- this procedure is for generic instantiation of + -- ZLib.Generic_Translate. + -- writing data to the File_Out. + + procedure Stamp; + -- Store the timestamp to the local variable. + + procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count); + -- Print the time statistic with the message. + + procedure Translate is new ZLib.Generic_Translate + (Data_In => Data_In, + Data_Out => Data_Out); + -- This procedure is moving data from File_In to File_Out + -- with compression or decompression, depend on initialization of + -- Filter parameter. + + ------------------- + -- Compare_Files -- + ------------------- + + procedure Compare_Files (Left, Right : String) is + Left_File, Right_File : File_Type; + begin + Open (Left_File, In_File, Left); + Open (Right_File, In_File, Right); + Compare_Streams (Stream (Left_File).all, Stream (Right_File).all); + Close (Left_File); + Close (Right_File); + end Compare_Files; + + --------------------- + -- Compare_Streams -- + --------------------- + + procedure Compare_Streams + (Left, Right : in out Ada.Streams.Root_Stream_Type'Class) + is + Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#); + Left_Last, Right_Last : Stream_Element_Offset; + begin + loop + Read (Left, Left_Buffer, Left_Last); + Read (Right, Right_Buffer, Right_Last); + + if Left_Last /= Right_Last then + Ada.Text_IO.Put_Line ("Compare error :" + & Stream_Element_Offset'Image (Left_Last) + & " /= " + & Stream_Element_Offset'Image (Right_Last)); + + raise Constraint_Error; + + elsif Left_Buffer (0 .. Left_Last) + /= Right_Buffer (0 .. Right_Last) + then + Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal."); + raise Constraint_Error; + + end if; + + exit when Left_Last < Left_Buffer'Last; + end loop; + end Compare_Streams; + + ------------------ + -- Copy_Streams -- + ------------------ + + procedure Copy_Streams + (Source, Target : in out Ada.Streams.Root_Stream_Type'Class; + Buffer_Size : in Stream_Element_Offset := 1024) + is + Buffer : Stream_Element_Array (1 .. Buffer_Size); + Last : Stream_Element_Offset; + begin + loop + Read (Source, Buffer, Last); + Write (Target, Buffer (1 .. Last)); + + exit when Last < Buffer'Last; + end loop; + end Copy_Streams; + + ------------- + -- Data_In -- + ------------- + + procedure Data_In + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) is + begin + Read (File_In, Item, Last); + end Data_In; + + -------------- + -- Data_Out -- + -------------- + + procedure Data_Out (Item : in Stream_Element_Array) is + begin + Write (File_Out, Item); + end Data_Out; + + ------------------- + -- Generate_File -- + ------------------- + + procedure Generate_File is + subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#; + + package Random_Elements is + new Ada.Numerics.Discrete_Random (Visible_Symbols); + + Gen : Random_Elements.Generator; + Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10; + + Buffer_Count : constant Count := File_Size / Buffer'Length; + -- Number of same buffers in the packet. + + Density : constant Count := 30; -- from 0 to Buffer'Length - 2; + + procedure Fill_Buffer (J, D : in Count); + -- Change the part of the buffer. + + ----------------- + -- Fill_Buffer -- + ----------------- + + procedure Fill_Buffer (J, D : in Count) is + begin + for K in 0 .. D loop + Buffer + (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1)) + := Random_Elements.Random (Gen); + + end loop; + end Fill_Buffer; + + begin + Random_Elements.Reset (Gen, Init_Random); + + Create (File_In, Out_File, In_File_Name); + + Fill_Buffer (1, Buffer'Length - 2); + + for J in 1 .. Buffer_Count loop + Write (File_In, Buffer); + + Fill_Buffer (J, Density); + end loop; + + -- fill remain size. + + Write + (File_In, + Buffer + (1 .. Stream_Element_Offset + (File_Size - Buffer'Length * Buffer_Count))); + + Flush (File_In); + Close (File_In); + end Generate_File; + + --------------------- + -- Print_Statistic -- + --------------------- + + procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is + use Ada.Calendar; + use Ada.Text_IO; + + package Count_IO is new Integer_IO (ZLib.Count); + + Curr_Dur : Duration := Clock - Time_Stamp; + begin + Put (Msg); + + Set_Col (20); + Ada.Text_IO.Put ("size ="); + + Count_IO.Put + (Data_Size, + Width => Stream_IO.Count'Image (File_Size)'Length); + + Put_Line (" duration =" & Duration'Image (Curr_Dur)); + end Print_Statistic; + + ----------- + -- Stamp -- + ----------- + + procedure Stamp is + begin + Time_Stamp := Ada.Calendar.Clock; + end Stamp; + +begin + Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version); + + loop + Generate_File; + + for Level in ZLib.Compression_Level'Range loop + + Ada.Text_IO.Put_Line ("Level =" + & ZLib.Compression_Level'Image (Level)); + + -- Test generic interface. + Open (File_In, In_File, In_File_Name); + Create (File_Out, Out_File, Z_File_Name); + + Stamp; + + -- Deflate using generic instantiation. + + ZLib.Deflate_Init + (Filter => Filter, + Level => Level, + Strategy => Strategy, + Header => Header); + + Translate (Filter); + Print_Statistic ("Generic compress", ZLib.Total_Out (Filter)); + ZLib.Close (Filter); + + Close (File_In); + Close (File_Out); + + Open (File_In, In_File, Z_File_Name); + Create (File_Out, Out_File, Out_File_Name); + + Stamp; + + -- Inflate using generic instantiation. + + ZLib.Inflate_Init (Filter, Header => Header); + + Translate (Filter); + Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter)); + + ZLib.Close (Filter); + + Close (File_In); + Close (File_Out); + + Compare_Files (In_File_Name, Out_File_Name); + + -- Test stream interface. + + -- Compress to the back stream. + + Open (File_In, In_File, In_File_Name); + Create (File_Back, Out_File, Z_File_Name); + + Stamp; + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.Out_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => True, + Level => Level, + Strategy => Strategy, + Header => Header); + + Copy_Streams + (Source => Stream (File_In).all, + Target => File_Z); + + -- Flushing internal buffers to the back stream. + + ZLib.Streams.Flush (File_Z, ZLib.Finish); + + Print_Statistic ("Write compress", + ZLib.Streams.Write_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + + Close (File_In); + Close (File_Back); + + -- Compare reading from original file and from + -- decompression stream. + + Open (File_In, In_File, In_File_Name); + Open (File_Back, In_File, Z_File_Name); + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.In_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => True, + Header => Header); + + Stamp; + Compare_Streams (Stream (File_In).all, File_Z); + + Print_Statistic ("Read decompress", + ZLib.Streams.Read_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + Close (File_In); + Close (File_Back); + + -- Compress by reading from compression stream. + + Open (File_Back, In_File, In_File_Name); + Create (File_Out, Out_File, Z_File_Name); + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.In_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => False, + Level => Level, + Strategy => Strategy, + Header => Header); + + Stamp; + Copy_Streams + (Source => File_Z, + Target => Stream (File_Out).all); + + Print_Statistic ("Read compress", + ZLib.Streams.Read_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + + Close (File_Out); + Close (File_Back); + + -- Decompress to decompression stream. + + Open (File_In, In_File, Z_File_Name); + Create (File_Back, Out_File, Out_File_Name); + + ZLib.Streams.Create + (Stream => File_Z, + Mode => ZLib.Streams.Out_Stream, + Back => ZLib.Streams.Stream_Access + (Stream (File_Back)), + Back_Compressed => False, + Header => Header); + + Stamp; + + Copy_Streams + (Source => Stream (File_In).all, + Target => File_Z); + + Print_Statistic ("Write decompress", + ZLib.Streams.Write_Total_Out (File_Z)); + + ZLib.Streams.Close (File_Z); + Close (File_In); + Close (File_Back); + + Compare_Files (In_File_Name, Out_File_Name); + end loop; + + Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok."); + + exit when not Continuous; + + File_Size := File_Size + 1; + end loop; +end Test; diff --git a/libz/contrib/ada/zlib-streams.adb b/libz/contrib/ada/zlib-streams.adb new file mode 100644 index 000000000..b6497bae2 --- /dev/null +++ b/libz/contrib/ada/zlib-streams.adb @@ -0,0 +1,225 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $ + +with Ada.Unchecked_Deallocation; + +package body ZLib.Streams is + + ----------- + -- Close -- + ----------- + + procedure Close (Stream : in out Stream_Type) is + procedure Free is new Ada.Unchecked_Deallocation + (Stream_Element_Array, Buffer_Access); + begin + if Stream.Mode = Out_Stream or Stream.Mode = Duplex then + -- We should flush the data written by the writer. + + Flush (Stream, Finish); + + Close (Stream.Writer); + end if; + + if Stream.Mode = In_Stream or Stream.Mode = Duplex then + Close (Stream.Reader); + Free (Stream.Buffer); + end if; + end Close; + + ------------ + -- Create -- + ------------ + + procedure Create + (Stream : out Stream_Type; + Mode : in Stream_Mode; + Back : in Stream_Access; + Back_Compressed : in Boolean; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Header : in Header_Type := Default; + Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size; + Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size) + is + + subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size); + + procedure Init_Filter + (Filter : in out Filter_Type; + Compress : in Boolean); + + ----------------- + -- Init_Filter -- + ----------------- + + procedure Init_Filter + (Filter : in out Filter_Type; + Compress : in Boolean) is + begin + if Compress then + Deflate_Init + (Filter, Level, Strategy, Header => Header); + else + Inflate_Init (Filter, Header => Header); + end if; + end Init_Filter; + + begin + Stream.Back := Back; + Stream.Mode := Mode; + + if Mode = Out_Stream or Mode = Duplex then + Init_Filter (Stream.Writer, Back_Compressed); + Stream.Buffer_Size := Write_Buffer_Size; + else + Stream.Buffer_Size := 0; + end if; + + if Mode = In_Stream or Mode = Duplex then + Init_Filter (Stream.Reader, not Back_Compressed); + + Stream.Buffer := new Buffer_Subtype; + Stream.Rest_First := Stream.Buffer'Last + 1; + Stream.Rest_Last := Stream.Buffer'Last; + end if; + end Create; + + ----------- + -- Flush -- + ----------- + + procedure Flush + (Stream : in out Stream_Type; + Mode : in Flush_Mode := Sync_Flush) + is + Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size); + Last : Stream_Element_Offset; + begin + loop + Flush (Stream.Writer, Buffer, Last, Mode); + + Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last)); + + exit when Last < Buffer'Last; + end loop; + end Flush; + + ------------- + -- Is_Open -- + ------------- + + function Is_Open (Stream : Stream_Type) return Boolean is + begin + return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer); + end Is_Open; + + ---------- + -- Read -- + ---------- + + procedure Read + (Stream : in out Stream_Type; + Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) + is + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset); + + ---------- + -- Read -- + ---------- + + procedure Read + (Item : out Stream_Element_Array; + Last : out Stream_Element_Offset) is + begin + Ada.Streams.Read (Stream.Back.all, Item, Last); + end Read; + + procedure Read is new ZLib.Read + (Read => Read, + Buffer => Stream.Buffer.all, + Rest_First => Stream.Rest_First, + Rest_Last => Stream.Rest_Last); + + begin + Read (Stream.Reader, Item, Last); + end Read; + + ------------------- + -- Read_Total_In -- + ------------------- + + function Read_Total_In (Stream : in Stream_Type) return Count is + begin + return Total_In (Stream.Reader); + end Read_Total_In; + + -------------------- + -- Read_Total_Out -- + -------------------- + + function Read_Total_Out (Stream : in Stream_Type) return Count is + begin + return Total_Out (Stream.Reader); + end Read_Total_Out; + + ----------- + -- Write -- + ----------- + + procedure Write + (Stream : in out Stream_Type; + Item : in Stream_Element_Array) + is + + procedure Write (Item : in Stream_Element_Array); + + ----------- + -- Write -- + ----------- + + procedure Write (Item : in Stream_Element_Array) is + begin + Ada.Streams.Write (Stream.Back.all, Item); + end Write; + + procedure Write is new ZLib.Write + (Write => Write, + Buffer_Size => Stream.Buffer_Size); + + begin + Write (Stream.Writer, Item, No_Flush); + end Write; + + -------------------- + -- Write_Total_In -- + -------------------- + + function Write_Total_In (Stream : in Stream_Type) return Count is + begin + return Total_In (Stream.Writer); + end Write_Total_In; + + --------------------- + -- Write_Total_Out -- + --------------------- + + function Write_Total_Out (Stream : in Stream_Type) return Count is + begin + return Total_Out (Stream.Writer); + end Write_Total_Out; + +end ZLib.Streams; diff --git a/libz/contrib/ada/zlib-streams.ads b/libz/contrib/ada/zlib-streams.ads new file mode 100644 index 000000000..f0193c6ba --- /dev/null +++ b/libz/contrib/ada/zlib-streams.ads @@ -0,0 +1,114 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $ + +package ZLib.Streams is + + type Stream_Mode is (In_Stream, Out_Stream, Duplex); + + type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class; + + type Stream_Type is + new Ada.Streams.Root_Stream_Type with private; + + procedure Read + (Stream : in out Stream_Type; + Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + + procedure Write + (Stream : in out Stream_Type; + Item : in Ada.Streams.Stream_Element_Array); + + procedure Flush + (Stream : in out Stream_Type; + Mode : in Flush_Mode := Sync_Flush); + -- Flush the written data to the back stream, + -- all data placed to the compressor is flushing to the Back stream. + -- Should not be used untill necessary, becouse it is decreasing + -- compression. + + function Read_Total_In (Stream : in Stream_Type) return Count; + pragma Inline (Read_Total_In); + -- Return total number of bytes read from back stream so far. + + function Read_Total_Out (Stream : in Stream_Type) return Count; + pragma Inline (Read_Total_Out); + -- Return total number of bytes read so far. + + function Write_Total_In (Stream : in Stream_Type) return Count; + pragma Inline (Write_Total_In); + -- Return total number of bytes written so far. + + function Write_Total_Out (Stream : in Stream_Type) return Count; + pragma Inline (Write_Total_Out); + -- Return total number of bytes written to the back stream. + + procedure Create + (Stream : out Stream_Type; + Mode : in Stream_Mode; + Back : in Stream_Access; + Back_Compressed : in Boolean; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Header : in Header_Type := Default; + Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size; + Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size); + -- Create the Comression/Decompression stream. + -- If mode is In_Stream then Write operation is disabled. + -- If mode is Out_Stream then Read operation is disabled. + + -- If Back_Compressed is true then + -- Data written to the Stream is compressing to the Back stream + -- and data read from the Stream is decompressed data from the Back stream. + + -- If Back_Compressed is false then + -- Data written to the Stream is decompressing to the Back stream + -- and data read from the Stream is compressed data from the Back stream. + + -- !!! When the Need_Header is False ZLib-Ada is using undocumented + -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers. + + function Is_Open (Stream : Stream_Type) return Boolean; + + procedure Close (Stream : in out Stream_Type); + +private + + use Ada.Streams; + + type Buffer_Access is access all Stream_Element_Array; + + type Stream_Type + is new Root_Stream_Type with + record + Mode : Stream_Mode; + + Buffer : Buffer_Access; + Rest_First : Stream_Element_Offset; + Rest_Last : Stream_Element_Offset; + -- Buffer for Read operation. + -- We need to have this buffer in the record + -- becouse not all read data from back stream + -- could be processed during the read operation. + + Buffer_Size : Stream_Element_Offset; + -- Buffer size for write operation. + -- We do not need to have this buffer + -- in the record becouse all data could be + -- processed in the write operation. + + Back : Stream_Access; + Reader : Filter_Type; + Writer : Filter_Type; + end record; + +end ZLib.Streams; diff --git a/libz/contrib/ada/zlib-thin.adb b/libz/contrib/ada/zlib-thin.adb new file mode 100644 index 000000000..0ca4a7120 --- /dev/null +++ b/libz/contrib/ada/zlib-thin.adb @@ -0,0 +1,141 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $ + +package body ZLib.Thin is + + ZLIB_VERSION : constant Chars_Ptr := zlibVersion; + + Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit; + + -------------- + -- Avail_In -- + -------------- + + function Avail_In (Strm : in Z_Stream) return UInt is + begin + return Strm.Avail_In; + end Avail_In; + + --------------- + -- Avail_Out -- + --------------- + + function Avail_Out (Strm : in Z_Stream) return UInt is + begin + return Strm.Avail_Out; + end Avail_Out; + + ------------------ + -- Deflate_Init -- + ------------------ + + function Deflate_Init + (strm : Z_Streamp; + level : Int; + method : Int; + windowBits : Int; + memLevel : Int; + strategy : Int) + return Int is + begin + return deflateInit2 + (strm, + level, + method, + windowBits, + memLevel, + strategy, + ZLIB_VERSION, + Z_Stream_Size); + end Deflate_Init; + + ------------------ + -- Inflate_Init -- + ------------------ + + function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is + begin + return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size); + end Inflate_Init; + + ------------------------ + -- Last_Error_Message -- + ------------------------ + + function Last_Error_Message (Strm : in Z_Stream) return String is + use Interfaces.C.Strings; + begin + if Strm.msg = Null_Ptr then + return ""; + else + return Value (Strm.msg); + end if; + end Last_Error_Message; + + ------------ + -- Set_In -- + ------------ + + procedure Set_In + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt) is + begin + Strm.Next_In := Buffer; + Strm.Avail_In := Size; + end Set_In; + + ------------------ + -- Set_Mem_Func -- + ------------------ + + procedure Set_Mem_Func + (Strm : in out Z_Stream; + Opaque : in Voidp; + Alloc : in alloc_func; + Free : in free_func) is + begin + Strm.opaque := Opaque; + Strm.zalloc := Alloc; + Strm.zfree := Free; + end Set_Mem_Func; + + ------------- + -- Set_Out -- + ------------- + + procedure Set_Out + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt) is + begin + Strm.Next_Out := Buffer; + Strm.Avail_Out := Size; + end Set_Out; + + -------------- + -- Total_In -- + -------------- + + function Total_In (Strm : in Z_Stream) return ULong is + begin + return Strm.Total_In; + end Total_In; + + --------------- + -- Total_Out -- + --------------- + + function Total_Out (Strm : in Z_Stream) return ULong is + begin + return Strm.Total_Out; + end Total_Out; + +end ZLib.Thin; diff --git a/libz/contrib/ada/zlib-thin.ads b/libz/contrib/ada/zlib-thin.ads new file mode 100644 index 000000000..d4407eb80 --- /dev/null +++ b/libz/contrib/ada/zlib-thin.ads @@ -0,0 +1,450 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $ + +with Interfaces.C.Strings; + +with System; + +private package ZLib.Thin is + + -- From zconf.h + + MAX_MEM_LEVEL : constant := 9; -- zconf.h:105 + -- zconf.h:105 + MAX_WBITS : constant := 15; -- zconf.h:115 + -- 32K LZ77 window + -- zconf.h:115 + SEEK_SET : constant := 8#0000#; -- zconf.h:244 + -- Seek from beginning of file. + -- zconf.h:244 + SEEK_CUR : constant := 1; -- zconf.h:245 + -- Seek from current position. + -- zconf.h:245 + SEEK_END : constant := 2; -- zconf.h:246 + -- Set file pointer to EOF plus "offset" + -- zconf.h:246 + + type Byte is new Interfaces.C.unsigned_char; -- 8 bits + -- zconf.h:214 + type UInt is new Interfaces.C.unsigned; -- 16 bits or more + -- zconf.h:216 + type Int is new Interfaces.C.int; + + type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more + -- zconf.h:217 + subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr; + + type ULong_Access is access ULong; + type Int_Access is access Int; + + subtype Voidp is System.Address; -- zconf.h:232 + + subtype Byte_Access is Voidp; + + Nul : constant Voidp := System.Null_Address; + -- end from zconf + + Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125 + -- zlib.h:125 + Z_PARTIAL_FLUSH : constant := 1; -- zlib.h:126 + -- will be removed, use + -- Z_SYNC_FLUSH instead + -- zlib.h:126 + Z_SYNC_FLUSH : constant := 2; -- zlib.h:127 + -- zlib.h:127 + Z_FULL_FLUSH : constant := 3; -- zlib.h:128 + -- zlib.h:128 + Z_FINISH : constant := 4; -- zlib.h:129 + -- zlib.h:129 + Z_OK : constant := 8#0000#; -- zlib.h:132 + -- zlib.h:132 + Z_STREAM_END : constant := 1; -- zlib.h:133 + -- zlib.h:133 + Z_NEED_DICT : constant := 2; -- zlib.h:134 + -- zlib.h:134 + Z_ERRNO : constant := -1; -- zlib.h:135 + -- zlib.h:135 + Z_STREAM_ERROR : constant := -2; -- zlib.h:136 + -- zlib.h:136 + Z_DATA_ERROR : constant := -3; -- zlib.h:137 + -- zlib.h:137 + Z_MEM_ERROR : constant := -4; -- zlib.h:138 + -- zlib.h:138 + Z_BUF_ERROR : constant := -5; -- zlib.h:139 + -- zlib.h:139 + Z_VERSION_ERROR : constant := -6; -- zlib.h:140 + -- zlib.h:140 + Z_NO_COMPRESSION : constant := 8#0000#; -- zlib.h:145 + -- zlib.h:145 + Z_BEST_SPEED : constant := 1; -- zlib.h:146 + -- zlib.h:146 + Z_BEST_COMPRESSION : constant := 9; -- zlib.h:147 + -- zlib.h:147 + Z_DEFAULT_COMPRESSION : constant := -1; -- zlib.h:148 + -- zlib.h:148 + Z_FILTERED : constant := 1; -- zlib.h:151 + -- zlib.h:151 + Z_HUFFMAN_ONLY : constant := 2; -- zlib.h:152 + -- zlib.h:152 + Z_DEFAULT_STRATEGY : constant := 8#0000#; -- zlib.h:153 + -- zlib.h:153 + Z_BINARY : constant := 8#0000#; -- zlib.h:156 + -- zlib.h:156 + Z_ASCII : constant := 1; -- zlib.h:157 + -- zlib.h:157 + Z_UNKNOWN : constant := 2; -- zlib.h:158 + -- zlib.h:158 + Z_DEFLATED : constant := 8; -- zlib.h:161 + -- zlib.h:161 + Z_NULL : constant := 8#0000#; -- zlib.h:164 + -- for initializing zalloc, zfree, opaque + -- zlib.h:164 + type gzFile is new Voidp; -- zlib.h:646 + + type Z_Stream is private; + + type Z_Streamp is access all Z_Stream; -- zlib.h:89 + + type alloc_func is access function + (Opaque : Voidp; + Items : UInt; + Size : UInt) + return Voidp; -- zlib.h:63 + + type free_func is access procedure (opaque : Voidp; address : Voidp); + + function zlibVersion return Chars_Ptr; + + function Deflate (strm : Z_Streamp; flush : Int) return Int; + + function DeflateEnd (strm : Z_Streamp) return Int; + + function Inflate (strm : Z_Streamp; flush : Int) return Int; + + function InflateEnd (strm : Z_Streamp) return Int; + + function deflateSetDictionary + (strm : Z_Streamp; + dictionary : Byte_Access; + dictLength : UInt) + return Int; + + function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int; + -- zlib.h:478 + + function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495 + + function deflateParams + (strm : Z_Streamp; + level : Int; + strategy : Int) + return Int; -- zlib.h:506 + + function inflateSetDictionary + (strm : Z_Streamp; + dictionary : Byte_Access; + dictLength : UInt) + return Int; -- zlib.h:548 + + function inflateSync (strm : Z_Streamp) return Int; -- zlib.h:565 + + function inflateReset (strm : Z_Streamp) return Int; -- zlib.h:580 + + function compress + (dest : Byte_Access; + destLen : ULong_Access; + source : Byte_Access; + sourceLen : ULong) + return Int; -- zlib.h:601 + + function compress2 + (dest : Byte_Access; + destLen : ULong_Access; + source : Byte_Access; + sourceLen : ULong; + level : Int) + return Int; -- zlib.h:615 + + function uncompress + (dest : Byte_Access; + destLen : ULong_Access; + source : Byte_Access; + sourceLen : ULong) + return Int; + + function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile; + + function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile; + + function gzsetparams + (file : gzFile; + level : Int; + strategy : Int) + return Int; + + function gzread + (file : gzFile; + buf : Voidp; + len : UInt) + return Int; + + function gzwrite + (file : in gzFile; + buf : in Voidp; + len : in UInt) + return Int; + + function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int; + + function gzputs (file : in gzFile; s : in Chars_Ptr) return Int; + + function gzgets + (file : gzFile; + buf : Chars_Ptr; + len : Int) + return Chars_Ptr; + + function gzputc (file : gzFile; char : Int) return Int; + + function gzgetc (file : gzFile) return Int; + + function gzflush (file : gzFile; flush : Int) return Int; + + function gzseek + (file : gzFile; + offset : Int; + whence : Int) + return Int; + + function gzrewind (file : gzFile) return Int; + + function gztell (file : gzFile) return Int; + + function gzeof (file : gzFile) return Int; + + function gzclose (file : gzFile) return Int; + + function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr; + + function adler32 + (adler : ULong; + buf : Byte_Access; + len : UInt) + return ULong; + + function crc32 + (crc : ULong; + buf : Byte_Access; + len : UInt) + return ULong; + + function deflateInit + (strm : Z_Streamp; + level : Int; + version : Chars_Ptr; + stream_size : Int) + return Int; + + function deflateInit2 + (strm : Z_Streamp; + level : Int; + method : Int; + windowBits : Int; + memLevel : Int; + strategy : Int; + version : Chars_Ptr; + stream_size : Int) + return Int; + + function Deflate_Init + (strm : Z_Streamp; + level : Int; + method : Int; + windowBits : Int; + memLevel : Int; + strategy : Int) + return Int; + pragma Inline (Deflate_Init); + + function inflateInit + (strm : Z_Streamp; + version : Chars_Ptr; + stream_size : Int) + return Int; + + function inflateInit2 + (strm : in Z_Streamp; + windowBits : in Int; + version : in Chars_Ptr; + stream_size : in Int) + return Int; + + function inflateBackInit + (strm : in Z_Streamp; + windowBits : in Int; + window : in Byte_Access; + version : in Chars_Ptr; + stream_size : in Int) + return Int; + -- Size of window have to be 2**windowBits. + + function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int; + pragma Inline (Inflate_Init); + + function zError (err : Int) return Chars_Ptr; + + function inflateSyncPoint (z : Z_Streamp) return Int; + + function get_crc_table return ULong_Access; + + -- Interface to the available fields of the z_stream structure. + -- The application must update next_in and avail_in when avail_in has + -- dropped to zero. It must update next_out and avail_out when avail_out + -- has dropped to zero. The application must initialize zalloc, zfree and + -- opaque before calling the init function. + + procedure Set_In + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt); + pragma Inline (Set_In); + + procedure Set_Out + (Strm : in out Z_Stream; + Buffer : in Voidp; + Size : in UInt); + pragma Inline (Set_Out); + + procedure Set_Mem_Func + (Strm : in out Z_Stream; + Opaque : in Voidp; + Alloc : in alloc_func; + Free : in free_func); + pragma Inline (Set_Mem_Func); + + function Last_Error_Message (Strm : in Z_Stream) return String; + pragma Inline (Last_Error_Message); + + function Avail_Out (Strm : in Z_Stream) return UInt; + pragma Inline (Avail_Out); + + function Avail_In (Strm : in Z_Stream) return UInt; + pragma Inline (Avail_In); + + function Total_In (Strm : in Z_Stream) return ULong; + pragma Inline (Total_In); + + function Total_Out (Strm : in Z_Stream) return ULong; + pragma Inline (Total_Out); + + function inflateCopy + (dest : in Z_Streamp; + Source : in Z_Streamp) + return Int; + + function compressBound (Source_Len : in ULong) return ULong; + + function deflateBound + (Strm : in Z_Streamp; + Source_Len : in ULong) + return ULong; + + function gzungetc (C : in Int; File : in gzFile) return Int; + + function zlibCompileFlags return ULong; + +private + + type Z_Stream is record -- zlib.h:68 + Next_In : Voidp := Nul; -- next input byte + Avail_In : UInt := 0; -- number of bytes available at next_in + Total_In : ULong := 0; -- total nb of input bytes read so far + Next_Out : Voidp := Nul; -- next output byte should be put there + Avail_Out : UInt := 0; -- remaining free space at next_out + Total_Out : ULong := 0; -- total nb of bytes output so far + msg : Chars_Ptr; -- last error message, NULL if no error + state : Voidp; -- not visible by applications + zalloc : alloc_func := null; -- used to allocate the internal state + zfree : free_func := null; -- used to free the internal state + opaque : Voidp; -- private data object passed to + -- zalloc and zfree + data_type : Int; -- best guess about the data type: + -- ascii or binary + adler : ULong; -- adler32 value of the uncompressed + -- data + reserved : ULong; -- reserved for future use + end record; + + pragma Convention (C, Z_Stream); + + pragma Import (C, zlibVersion, "zlibVersion"); + pragma Import (C, Deflate, "deflate"); + pragma Import (C, DeflateEnd, "deflateEnd"); + pragma Import (C, Inflate, "inflate"); + pragma Import (C, InflateEnd, "inflateEnd"); + pragma Import (C, deflateSetDictionary, "deflateSetDictionary"); + pragma Import (C, deflateCopy, "deflateCopy"); + pragma Import (C, deflateReset, "deflateReset"); + pragma Import (C, deflateParams, "deflateParams"); + pragma Import (C, inflateSetDictionary, "inflateSetDictionary"); + pragma Import (C, inflateSync, "inflateSync"); + pragma Import (C, inflateReset, "inflateReset"); + pragma Import (C, compress, "compress"); + pragma Import (C, compress2, "compress2"); + pragma Import (C, uncompress, "uncompress"); + pragma Import (C, gzopen, "gzopen"); + pragma Import (C, gzdopen, "gzdopen"); + pragma Import (C, gzsetparams, "gzsetparams"); + pragma Import (C, gzread, "gzread"); + pragma Import (C, gzwrite, "gzwrite"); + pragma Import (C, gzprintf, "gzprintf"); + pragma Import (C, gzputs, "gzputs"); + pragma Import (C, gzgets, "gzgets"); + pragma Import (C, gzputc, "gzputc"); + pragma Import (C, gzgetc, "gzgetc"); + pragma Import (C, gzflush, "gzflush"); + pragma Import (C, gzseek, "gzseek"); + pragma Import (C, gzrewind, "gzrewind"); + pragma Import (C, gztell, "gztell"); + pragma Import (C, gzeof, "gzeof"); + pragma Import (C, gzclose, "gzclose"); + pragma Import (C, gzerror, "gzerror"); + pragma Import (C, adler32, "adler32"); + pragma Import (C, crc32, "crc32"); + pragma Import (C, deflateInit, "deflateInit_"); + pragma Import (C, inflateInit, "inflateInit_"); + pragma Import (C, deflateInit2, "deflateInit2_"); + pragma Import (C, inflateInit2, "inflateInit2_"); + pragma Import (C, zError, "zError"); + pragma Import (C, inflateSyncPoint, "inflateSyncPoint"); + pragma Import (C, get_crc_table, "get_crc_table"); + + -- since zlib 1.2.0: + + pragma Import (C, inflateCopy, "inflateCopy"); + pragma Import (C, compressBound, "compressBound"); + pragma Import (C, deflateBound, "deflateBound"); + pragma Import (C, gzungetc, "gzungetc"); + pragma Import (C, zlibCompileFlags, "zlibCompileFlags"); + + pragma Import (C, inflateBackInit, "inflateBackInit_"); + + -- I stopped binding the inflateBack routines, becouse realize that + -- it does not support zlib and gzip headers for now, and have no + -- symmetric deflateBack routines. + -- ZLib-Ada is symmetric regarding deflate/inflate data transformation + -- and has a similar generic callback interface for the + -- deflate/inflate transformation based on the regular Deflate/Inflate + -- routines. + + -- pragma Import (C, inflateBack, "inflateBack"); + -- pragma Import (C, inflateBackEnd, "inflateBackEnd"); + +end ZLib.Thin; diff --git a/libz/contrib/ada/zlib.adb b/libz/contrib/ada/zlib.adb new file mode 100644 index 000000000..8b6fd686a --- /dev/null +++ b/libz/contrib/ada/zlib.adb @@ -0,0 +1,701 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- + +-- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $ + +with Ada.Exceptions; +with Ada.Unchecked_Conversion; +with Ada.Unchecked_Deallocation; + +with Interfaces.C.Strings; + +with ZLib.Thin; + +package body ZLib is + + use type Thin.Int; + + type Z_Stream is new Thin.Z_Stream; + + type Return_Code_Enum is + (OK, + STREAM_END, + NEED_DICT, + ERRNO, + STREAM_ERROR, + DATA_ERROR, + MEM_ERROR, + BUF_ERROR, + VERSION_ERROR); + + type Flate_Step_Function is access + function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int; + pragma Convention (C, Flate_Step_Function); + + type Flate_End_Function is access + function (Ctrm : in Thin.Z_Streamp) return Thin.Int; + pragma Convention (C, Flate_End_Function); + + type Flate_Type is record + Step : Flate_Step_Function; + Done : Flate_End_Function; + end record; + + subtype Footer_Array is Stream_Element_Array (1 .. 8); + + Simple_GZip_Header : constant Stream_Element_Array (1 .. 10) + := (16#1f#, 16#8b#, -- Magic header + 16#08#, -- Z_DEFLATED + 16#00#, -- Flags + 16#00#, 16#00#, 16#00#, 16#00#, -- Time + 16#00#, -- XFlags + 16#03# -- OS code + ); + -- The simplest gzip header is not for informational, but just for + -- gzip format compatibility. + -- Note that some code below is using assumption + -- Simple_GZip_Header'Last > Footer_Array'Last, so do not make + -- Simple_GZip_Header'Last <= Footer_Array'Last. + + Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum + := (0 => OK, + 1 => STREAM_END, + 2 => NEED_DICT, + -1 => ERRNO, + -2 => STREAM_ERROR, + -3 => DATA_ERROR, + -4 => MEM_ERROR, + -5 => BUF_ERROR, + -6 => VERSION_ERROR); + + Flate : constant array (Boolean) of Flate_Type + := (True => (Step => Thin.Deflate'Access, + Done => Thin.DeflateEnd'Access), + False => (Step => Thin.Inflate'Access, + Done => Thin.InflateEnd'Access)); + + Flush_Finish : constant array (Boolean) of Flush_Mode + := (True => Finish, False => No_Flush); + + procedure Raise_Error (Stream : in Z_Stream); + pragma Inline (Raise_Error); + + procedure Raise_Error (Message : in String); + pragma Inline (Raise_Error); + + procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int); + + procedure Free is new Ada.Unchecked_Deallocation + (Z_Stream, Z_Stream_Access); + + function To_Thin_Access is new Ada.Unchecked_Conversion + (Z_Stream_Access, Thin.Z_Streamp); + + procedure Translate_GZip + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + -- Separate translate routine for make gzip header. + + procedure Translate_Auto + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + -- translate routine without additional headers. + + ----------------- + -- Check_Error -- + ----------------- + + procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is + use type Thin.Int; + begin + if Code /= Thin.Z_OK then + Raise_Error + (Return_Code_Enum'Image (Return_Code (Code)) + & ": " & Last_Error_Message (Stream)); + end if; + end Check_Error; + + ----------- + -- Close -- + ----------- + + procedure Close + (Filter : in out Filter_Type; + Ignore_Error : in Boolean := False) + is + Code : Thin.Int; + begin + if not Ignore_Error and then not Is_Open (Filter) then + raise Status_Error; + end if; + + Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm)); + + if Ignore_Error or else Code = Thin.Z_OK then + Free (Filter.Strm); + else + declare + Error_Message : constant String + := Last_Error_Message (Filter.Strm.all); + begin + Free (Filter.Strm); + Ada.Exceptions.Raise_Exception + (ZLib_Error'Identity, + Return_Code_Enum'Image (Return_Code (Code)) + & ": " & Error_Message); + end; + end if; + end Close; + + ----------- + -- CRC32 -- + ----------- + + function CRC32 + (CRC : in Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array) + return Unsigned_32 + is + use Thin; + begin + return Unsigned_32 (crc32 (ULong (CRC), + Data'Address, + Data'Length)); + end CRC32; + + procedure CRC32 + (CRC : in out Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array) is + begin + CRC := CRC32 (CRC, Data); + end CRC32; + + ------------------ + -- Deflate_Init -- + ------------------ + + procedure Deflate_Init + (Filter : in out Filter_Type; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Method : in Compression_Method := Deflated; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Memory_Level : in Memory_Level_Type := Default_Memory_Level; + Header : in Header_Type := Default) + is + use type Thin.Int; + Win_Bits : Thin.Int := Thin.Int (Window_Bits); + begin + if Is_Open (Filter) then + raise Status_Error; + end if; + + -- We allow ZLib to make header only in case of default header type. + -- Otherwise we would either do header by ourselfs, or do not do + -- header at all. + + if Header = None or else Header = GZip then + Win_Bits := -Win_Bits; + end if; + + -- For the GZip CRC calculation and make headers. + + if Header = GZip then + Filter.CRC := 0; + Filter.Offset := Simple_GZip_Header'First; + else + Filter.Offset := Simple_GZip_Header'Last + 1; + end if; + + Filter.Strm := new Z_Stream; + Filter.Compression := True; + Filter.Stream_End := False; + Filter.Header := Header; + + if Thin.Deflate_Init + (To_Thin_Access (Filter.Strm), + Level => Thin.Int (Level), + method => Thin.Int (Method), + windowBits => Win_Bits, + memLevel => Thin.Int (Memory_Level), + strategy => Thin.Int (Strategy)) /= Thin.Z_OK + then + Raise_Error (Filter.Strm.all); + end if; + end Deflate_Init; + + ----------- + -- Flush -- + ----------- + + procedure Flush + (Filter : in out Filter_Type; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) + is + No_Data : Stream_Element_Array := (1 .. 0 => 0); + Last : Stream_Element_Offset; + begin + Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush); + end Flush; + + ----------------------- + -- Generic_Translate -- + ----------------------- + + procedure Generic_Translate + (Filter : in out ZLib.Filter_Type; + In_Buffer_Size : in Integer := Default_Buffer_Size; + Out_Buffer_Size : in Integer := Default_Buffer_Size) + is + In_Buffer : Stream_Element_Array + (1 .. Stream_Element_Offset (In_Buffer_Size)); + Out_Buffer : Stream_Element_Array + (1 .. Stream_Element_Offset (Out_Buffer_Size)); + Last : Stream_Element_Offset; + In_Last : Stream_Element_Offset; + In_First : Stream_Element_Offset; + Out_Last : Stream_Element_Offset; + begin + Main : loop + Data_In (In_Buffer, Last); + + In_First := In_Buffer'First; + + loop + Translate + (Filter => Filter, + In_Data => In_Buffer (In_First .. Last), + In_Last => In_Last, + Out_Data => Out_Buffer, + Out_Last => Out_Last, + Flush => Flush_Finish (Last < In_Buffer'First)); + + if Out_Buffer'First <= Out_Last then + Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last)); + end if; + + exit Main when Stream_End (Filter); + + -- The end of in buffer. + + exit when In_Last = Last; + + In_First := In_Last + 1; + end loop; + end loop Main; + + end Generic_Translate; + + ------------------ + -- Inflate_Init -- + ------------------ + + procedure Inflate_Init + (Filter : in out Filter_Type; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Header : in Header_Type := Default) + is + use type Thin.Int; + Win_Bits : Thin.Int := Thin.Int (Window_Bits); + + procedure Check_Version; + -- Check the latest header types compatibility. + + procedure Check_Version is + begin + if Version <= "1.1.4" then + Raise_Error + ("Inflate header type " & Header_Type'Image (Header) + & " incompatible with ZLib version " & Version); + end if; + end Check_Version; + + begin + if Is_Open (Filter) then + raise Status_Error; + end if; + + case Header is + when None => + Check_Version; + + -- Inflate data without headers determined + -- by negative Win_Bits. + + Win_Bits := -Win_Bits; + when GZip => + Check_Version; + + -- Inflate gzip data defined by flag 16. + + Win_Bits := Win_Bits + 16; + when Auto => + Check_Version; + + -- Inflate with automatic detection + -- of gzip or native header defined by flag 32. + + Win_Bits := Win_Bits + 32; + when Default => null; + end case; + + Filter.Strm := new Z_Stream; + Filter.Compression := False; + Filter.Stream_End := False; + Filter.Header := Header; + + if Thin.Inflate_Init + (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK + then + Raise_Error (Filter.Strm.all); + end if; + end Inflate_Init; + + ------------- + -- Is_Open -- + ------------- + + function Is_Open (Filter : in Filter_Type) return Boolean is + begin + return Filter.Strm /= null; + end Is_Open; + + ----------------- + -- Raise_Error -- + ----------------- + + procedure Raise_Error (Message : in String) is + begin + Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message); + end Raise_Error; + + procedure Raise_Error (Stream : in Z_Stream) is + begin + Raise_Error (Last_Error_Message (Stream)); + end Raise_Error; + + ---------- + -- Read -- + ---------- + + procedure Read + (Filter : in out Filter_Type; + Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode := No_Flush) + is + In_Last : Stream_Element_Offset; + Item_First : Ada.Streams.Stream_Element_Offset := Item'First; + V_Flush : Flush_Mode := Flush; + + begin + pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1); + pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last); + + loop + if Rest_Last = Buffer'First - 1 then + V_Flush := Finish; + + elsif Rest_First > Rest_Last then + Read (Buffer, Rest_Last); + Rest_First := Buffer'First; + + if Rest_Last < Buffer'First then + V_Flush := Finish; + end if; + end if; + + Translate + (Filter => Filter, + In_Data => Buffer (Rest_First .. Rest_Last), + In_Last => In_Last, + Out_Data => Item (Item_First .. Item'Last), + Out_Last => Last, + Flush => V_Flush); + + Rest_First := In_Last + 1; + + exit when Stream_End (Filter) + or else Last = Item'Last + or else (Last >= Item'First and then Allow_Read_Some); + + Item_First := Last + 1; + end loop; + end Read; + + ---------------- + -- Stream_End -- + ---------------- + + function Stream_End (Filter : in Filter_Type) return Boolean is + begin + if Filter.Header = GZip and Filter.Compression then + return Filter.Stream_End + and then Filter.Offset = Footer_Array'Last + 1; + else + return Filter.Stream_End; + end if; + end Stream_End; + + -------------- + -- Total_In -- + -------------- + + function Total_In (Filter : in Filter_Type) return Count is + begin + return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all)); + end Total_In; + + --------------- + -- Total_Out -- + --------------- + + function Total_Out (Filter : in Filter_Type) return Count is + begin + return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all)); + end Total_Out; + + --------------- + -- Translate -- + --------------- + + procedure Translate + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) is + begin + if Filter.Header = GZip and then Filter.Compression then + Translate_GZip + (Filter => Filter, + In_Data => In_Data, + In_Last => In_Last, + Out_Data => Out_Data, + Out_Last => Out_Last, + Flush => Flush); + else + Translate_Auto + (Filter => Filter, + In_Data => In_Data, + In_Last => In_Last, + Out_Data => Out_Data, + Out_Last => Out_Last, + Flush => Flush); + end if; + end Translate; + + -------------------- + -- Translate_Auto -- + -------------------- + + procedure Translate_Auto + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) + is + use type Thin.Int; + Code : Thin.Int; + + begin + if not Is_Open (Filter) then + raise Status_Error; + end if; + + if Out_Data'Length = 0 and then In_Data'Length = 0 then + raise Constraint_Error; + end if; + + Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length); + Set_In (Filter.Strm.all, In_Data'Address, In_Data'Length); + + Code := Flate (Filter.Compression).Step + (To_Thin_Access (Filter.Strm), + Thin.Int (Flush)); + + if Code = Thin.Z_STREAM_END then + Filter.Stream_End := True; + else + Check_Error (Filter.Strm.all, Code); + end if; + + In_Last := In_Data'Last + - Stream_Element_Offset (Avail_In (Filter.Strm.all)); + Out_Last := Out_Data'Last + - Stream_Element_Offset (Avail_Out (Filter.Strm.all)); + end Translate_Auto; + + -------------------- + -- Translate_GZip -- + -------------------- + + procedure Translate_GZip + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode) + is + Out_First : Stream_Element_Offset; + + procedure Add_Data (Data : in Stream_Element_Array); + -- Add data to stream from the Filter.Offset till necessary, + -- used for add gzip headr/footer. + + procedure Put_32 + (Item : in out Stream_Element_Array; + Data : in Unsigned_32); + pragma Inline (Put_32); + + -------------- + -- Add_Data -- + -------------- + + procedure Add_Data (Data : in Stream_Element_Array) is + Data_First : Stream_Element_Offset renames Filter.Offset; + Data_Last : Stream_Element_Offset; + Data_Len : Stream_Element_Offset; -- -1 + Out_Len : Stream_Element_Offset; -- -1 + begin + Out_First := Out_Last + 1; + + if Data_First > Data'Last then + return; + end if; + + Data_Len := Data'Last - Data_First; + Out_Len := Out_Data'Last - Out_First; + + if Data_Len <= Out_Len then + Out_Last := Out_First + Data_Len; + Data_Last := Data'Last; + else + Out_Last := Out_Data'Last; + Data_Last := Data_First + Out_Len; + end if; + + Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last); + + Data_First := Data_Last + 1; + Out_First := Out_Last + 1; + end Add_Data; + + ------------ + -- Put_32 -- + ------------ + + procedure Put_32 + (Item : in out Stream_Element_Array; + Data : in Unsigned_32) + is + D : Unsigned_32 := Data; + begin + for J in Item'First .. Item'First + 3 loop + Item (J) := Stream_Element (D and 16#FF#); + D := Shift_Right (D, 8); + end loop; + end Put_32; + + begin + Out_Last := Out_Data'First - 1; + + if not Filter.Stream_End then + Add_Data (Simple_GZip_Header); + + Translate_Auto + (Filter => Filter, + In_Data => In_Data, + In_Last => In_Last, + Out_Data => Out_Data (Out_First .. Out_Data'Last), + Out_Last => Out_Last, + Flush => Flush); + + CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last)); + end if; + + if Filter.Stream_End and then Out_Last <= Out_Data'Last then + -- This detection method would work only when + -- Simple_GZip_Header'Last > Footer_Array'Last + + if Filter.Offset = Simple_GZip_Header'Last + 1 then + Filter.Offset := Footer_Array'First; + end if; + + declare + Footer : Footer_Array; + begin + Put_32 (Footer, Filter.CRC); + Put_32 (Footer (Footer'First + 4 .. Footer'Last), + Unsigned_32 (Total_In (Filter))); + Add_Data (Footer); + end; + end if; + end Translate_GZip; + + ------------- + -- Version -- + ------------- + + function Version return String is + begin + return Interfaces.C.Strings.Value (Thin.zlibVersion); + end Version; + + ----------- + -- Write -- + ----------- + + procedure Write + (Filter : in out Filter_Type; + Item : in Ada.Streams.Stream_Element_Array; + Flush : in Flush_Mode := No_Flush) + is + Buffer : Stream_Element_Array (1 .. Buffer_Size); + In_Last : Stream_Element_Offset; + Out_Last : Stream_Element_Offset; + In_First : Stream_Element_Offset := Item'First; + begin + if Item'Length = 0 and Flush = No_Flush then + return; + end if; + + loop + Translate + (Filter => Filter, + In_Data => Item (In_First .. Item'Last), + In_Last => In_Last, + Out_Data => Buffer, + Out_Last => Out_Last, + Flush => Flush); + + if Out_Last >= Buffer'First then + Write (Buffer (1 .. Out_Last)); + end if; + + exit when In_Last = Item'Last or Stream_End (Filter); + + In_First := In_Last + 1; + end loop; + end Write; + +end ZLib; diff --git a/libz/contrib/ada/zlib.ads b/libz/contrib/ada/zlib.ads new file mode 100644 index 000000000..79ffc4095 --- /dev/null +++ b/libz/contrib/ada/zlib.ads @@ -0,0 +1,328 @@ +------------------------------------------------------------------------------ +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- This library is free software; you can redistribute it and/or modify -- +-- it under the terms of the GNU General Public License as published by -- +-- the Free Software Foundation; either version 2 of the License, or (at -- +-- your option) any later version. -- +-- -- +-- This library is distributed in the hope that it will be useful, but -- +-- WITHOUT ANY WARRANTY; without even the implied warranty of -- +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- +-- General Public License for more details. -- +-- -- +-- You should have received a copy of the GNU General Public License -- +-- along with this library; if not, write to the Free Software Foundation, -- +-- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- +-- -- +-- As a special exception, if other files instantiate generics from this -- +-- unit, or you link this unit with other files to produce an executable, -- +-- this unit does not by itself cause the resulting executable to be -- +-- covered by the GNU General Public License. This exception does not -- +-- however invalidate any other reasons why the executable file might be -- +-- covered by the GNU Public License. -- +------------------------------------------------------------------------------ + +-- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $ + +with Ada.Streams; + +with Interfaces; + +package ZLib is + + ZLib_Error : exception; + Status_Error : exception; + + type Compression_Level is new Integer range -1 .. 9; + + type Flush_Mode is private; + + type Compression_Method is private; + + type Window_Bits_Type is new Integer range 8 .. 15; + + type Memory_Level_Type is new Integer range 1 .. 9; + + type Unsigned_32 is new Interfaces.Unsigned_32; + + type Strategy_Type is private; + + type Header_Type is (None, Auto, Default, GZip); + -- Header type usage have a some limitation for inflate. + -- See comment for Inflate_Init. + + subtype Count is Ada.Streams.Stream_Element_Count; + + Default_Memory_Level : constant Memory_Level_Type := 8; + Default_Window_Bits : constant Window_Bits_Type := 15; + + ---------------------------------- + -- Compression method constants -- + ---------------------------------- + + Deflated : constant Compression_Method; + -- Only one method allowed in this ZLib version + + --------------------------------- + -- Compression level constants -- + --------------------------------- + + No_Compression : constant Compression_Level := 0; + Best_Speed : constant Compression_Level := 1; + Best_Compression : constant Compression_Level := 9; + Default_Compression : constant Compression_Level := -1; + + -------------------------- + -- Flush mode constants -- + -------------------------- + + No_Flush : constant Flush_Mode; + -- Regular way for compression, no flush + + Partial_Flush : constant Flush_Mode; + -- Will be removed, use Z_SYNC_FLUSH instead + + Sync_Flush : constant Flush_Mode; + -- All pending output is flushed to the output buffer and the output + -- is aligned on a byte boundary, so that the decompressor can get all + -- input data available so far. (In particular avail_in is zero after the + -- call if enough output space has been provided before the call.) + -- Flushing may degrade compression for some compression algorithms and so + -- it should be used only when necessary. + + Block_Flush : constant Flush_Mode; + -- Z_BLOCK requests that inflate() stop + -- if and when it get to the next deflate block boundary. When decoding the + -- zlib or gzip format, this will cause inflate() to return immediately + -- after the header and before the first block. When doing a raw inflate, + -- inflate() will go ahead and process the first block, and will return + -- when it gets to the end of that block, or when it runs out of data. + + Full_Flush : constant Flush_Mode; + -- All output is flushed as with SYNC_FLUSH, and the compression state + -- is reset so that decompression can restart from this point if previous + -- compressed data has been damaged or if random access is desired. Using + -- Full_Flush too often can seriously degrade the compression. + + Finish : constant Flush_Mode; + -- Just for tell the compressor that input data is complete. + + ------------------------------------ + -- Compression strategy constants -- + ------------------------------------ + + -- RLE stategy could be used only in version 1.2.0 and later. + + Filtered : constant Strategy_Type; + Huffman_Only : constant Strategy_Type; + RLE : constant Strategy_Type; + Default_Strategy : constant Strategy_Type; + + Default_Buffer_Size : constant := 4096; + + type Filter_Type is tagged limited private; + -- The filter is for compression and for decompression. + -- The usage of the type is depend of its initialization. + + function Version return String; + pragma Inline (Version); + -- Return string representation of the ZLib version. + + procedure Deflate_Init + (Filter : in out Filter_Type; + Level : in Compression_Level := Default_Compression; + Strategy : in Strategy_Type := Default_Strategy; + Method : in Compression_Method := Deflated; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Memory_Level : in Memory_Level_Type := Default_Memory_Level; + Header : in Header_Type := Default); + -- Compressor initialization. + -- When Header parameter is Auto or Default, then default zlib header + -- would be provided for compressed data. + -- When Header is GZip, then gzip header would be set instead of + -- default header. + -- When Header is None, no header would be set for compressed data. + + procedure Inflate_Init + (Filter : in out Filter_Type; + Window_Bits : in Window_Bits_Type := Default_Window_Bits; + Header : in Header_Type := Default); + -- Decompressor initialization. + -- Default header type mean that ZLib default header is expecting in the + -- input compressed stream. + -- Header type None mean that no header is expecting in the input stream. + -- GZip header type mean that GZip header is expecting in the + -- input compressed stream. + -- Auto header type mean that header type (GZip or Native) would be + -- detected automatically in the input stream. + -- Note that header types parameter values None, GZip and Auto are + -- supported for inflate routine only in ZLib versions 1.2.0.2 and later. + -- Deflate_Init is supporting all header types. + + function Is_Open (Filter : in Filter_Type) return Boolean; + pragma Inline (Is_Open); + -- Is the filter opened for compression or decompression. + + procedure Close + (Filter : in out Filter_Type; + Ignore_Error : in Boolean := False); + -- Closing the compression or decompressor. + -- If stream is closing before the complete and Ignore_Error is False, + -- The exception would be raised. + + generic + with procedure Data_In + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + with procedure Data_Out + (Item : in Ada.Streams.Stream_Element_Array); + procedure Generic_Translate + (Filter : in out Filter_Type; + In_Buffer_Size : in Integer := Default_Buffer_Size; + Out_Buffer_Size : in Integer := Default_Buffer_Size); + -- Compress/decompress data fetch from Data_In routine and pass the result + -- to the Data_Out routine. User should provide Data_In and Data_Out + -- for compression/decompression data flow. + -- Compression or decompression depend on Filter initialization. + + function Total_In (Filter : in Filter_Type) return Count; + pragma Inline (Total_In); + -- Returns total number of input bytes read so far + + function Total_Out (Filter : in Filter_Type) return Count; + pragma Inline (Total_Out); + -- Returns total number of bytes output so far + + function CRC32 + (CRC : in Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array) + return Unsigned_32; + pragma Inline (CRC32); + -- Compute CRC32, it could be necessary for make gzip format + + procedure CRC32 + (CRC : in out Unsigned_32; + Data : in Ada.Streams.Stream_Element_Array); + pragma Inline (CRC32); + -- Compute CRC32, it could be necessary for make gzip format + + ------------------------------------------------- + -- Below is more complex low level routines. -- + ------------------------------------------------- + + procedure Translate + (Filter : in out Filter_Type; + In_Data : in Ada.Streams.Stream_Element_Array; + In_Last : out Ada.Streams.Stream_Element_Offset; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + -- Compress/decompress the In_Data buffer and place the result into + -- Out_Data. In_Last is the index of last element from In_Data accepted by + -- the Filter. Out_Last is the last element of the received data from + -- Filter. To tell the filter that incoming data are complete put the + -- Flush parameter to Finish. + + function Stream_End (Filter : in Filter_Type) return Boolean; + pragma Inline (Stream_End); + -- Return the true when the stream is complete. + + procedure Flush + (Filter : in out Filter_Type; + Out_Data : out Ada.Streams.Stream_Element_Array; + Out_Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode); + pragma Inline (Flush); + -- Flushing the data from the compressor. + + generic + with procedure Write + (Item : in Ada.Streams.Stream_Element_Array); + -- User should provide this routine for accept + -- compressed/decompressed data. + + Buffer_Size : in Ada.Streams.Stream_Element_Offset + := Default_Buffer_Size; + -- Buffer size for Write user routine. + + procedure Write + (Filter : in out Filter_Type; + Item : in Ada.Streams.Stream_Element_Array; + Flush : in Flush_Mode := No_Flush); + -- Compress/Decompress data from Item to the generic parameter procedure + -- Write. Output buffer size could be set in Buffer_Size generic parameter. + + generic + with procedure Read + (Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset); + -- User should provide data for compression/decompression + -- thru this routine. + + Buffer : in out Ada.Streams.Stream_Element_Array; + -- Buffer for keep remaining data from the previous + -- back read. + + Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset; + -- Rest_First have to be initialized to Buffer'Last + 1 + -- Rest_Last have to be initialized to Buffer'Last + -- before usage. + + Allow_Read_Some : in Boolean := False; + -- Is it allowed to return Last < Item'Last before end of data. + + procedure Read + (Filter : in out Filter_Type; + Item : out Ada.Streams.Stream_Element_Array; + Last : out Ada.Streams.Stream_Element_Offset; + Flush : in Flush_Mode := No_Flush); + -- Compress/Decompress data from generic parameter procedure Read to the + -- Item. User should provide Buffer and initialized Rest_First, Rest_Last + -- indicators. If Allow_Read_Some is True, Read routines could return + -- Last < Item'Last only at end of stream. + +private + + use Ada.Streams; + + pragma Assert (Ada.Streams.Stream_Element'Size = 8); + pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8); + + type Flush_Mode is new Integer range 0 .. 5; + + type Compression_Method is new Integer range 8 .. 8; + + type Strategy_Type is new Integer range 0 .. 3; + + No_Flush : constant Flush_Mode := 0; + Partial_Flush : constant Flush_Mode := 1; + Sync_Flush : constant Flush_Mode := 2; + Full_Flush : constant Flush_Mode := 3; + Finish : constant Flush_Mode := 4; + Block_Flush : constant Flush_Mode := 5; + + Filtered : constant Strategy_Type := 1; + Huffman_Only : constant Strategy_Type := 2; + RLE : constant Strategy_Type := 3; + Default_Strategy : constant Strategy_Type := 0; + + Deflated : constant Compression_Method := 8; + + type Z_Stream; + + type Z_Stream_Access is access all Z_Stream; + + type Filter_Type is tagged limited record + Strm : Z_Stream_Access; + Compression : Boolean; + Stream_End : Boolean; + Header : Header_Type; + CRC : Unsigned_32; + Offset : Stream_Element_Offset; + -- Offset for gzip header/footer output. + end record; + +end ZLib; diff --git a/libz/contrib/ada/zlib.gpr b/libz/contrib/ada/zlib.gpr new file mode 100644 index 000000000..296b22aa9 --- /dev/null +++ b/libz/contrib/ada/zlib.gpr @@ -0,0 +1,20 @@ +project Zlib is + + for Languages use ("Ada"); + for Source_Dirs use ("."); + for Object_Dir use "."; + for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo"); + + package Compiler is + for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst"); + end Compiler; + + package Linker is + for Default_Switches ("ada") use ("-lz"); + end Linker; + + package Builder is + for Default_Switches ("ada") use ("-s", "-gnatQ"); + end Builder; + +end Zlib; diff --git a/libz/contrib/amd64/amd64-match.S b/libz/contrib/amd64/amd64-match.S new file mode 100644 index 000000000..81d4a1c94 --- /dev/null +++ b/libz/contrib/amd64/amd64-match.S @@ -0,0 +1,452 @@ +/* + * match.S -- optimized version of longest_match() + * based on the similar work by Gilles Vollant, and Brian Raiter, written 1998 + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the BSD License. Use by owners of Che Guevarra + * parafernalia is prohibited, where possible, and highly discouraged + * elsewhere. + */ + +#ifndef NO_UNDERLINE +# define match_init _match_init +# define longest_match _longest_match +#endif + +#define scanend ebx +#define scanendw bx +#define chainlenwmask edx /* high word: current chain len low word: s->wmask */ +#define curmatch rsi +#define curmatchd esi +#define windowbestlen r8 +#define scanalign r9 +#define scanalignd r9d +#define window r10 +#define bestlen r11 +#define bestlend r11d +#define scanstart r12d +#define scanstartw r12w +#define scan r13 +#define nicematch r14d +#define limit r15 +#define limitd r15d +#define prev rcx + +/* + * The 258 is a "magic number, not a parameter -- changing it + * breaks the hell loose + */ +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ +#define LocalVarsSize (112) +#define _chainlenwmask ( 8-LocalVarsSize)(%rsp) +#define _windowbestlen (16-LocalVarsSize)(%rsp) +#define save_r14 (24-LocalVarsSize)(%rsp) +#define save_rsi (32-LocalVarsSize)(%rsp) +#define save_rbx (40-LocalVarsSize)(%rsp) +#define save_r12 (56-LocalVarsSize)(%rsp) +#define save_r13 (64-LocalVarsSize)(%rsp) +#define save_r15 (80-LocalVarsSize)(%rsp) + + +.globl match_init, longest_match + +/* + * On AMD64 the first argument of a function (in our case -- the pointer to + * deflate_state structure) is passed in %rdi, hence our offsets below are + * all off of that. + */ + +/* you can check the structure offset by running + +#include +#include +#include "deflate.h" + +void print_depl() +{ +deflate_state ds; +deflate_state *s=&ds; +printf("size pointer=%u\n",(int)sizeof(void*)); + +printf("#define dsWSize (%3u)(%%rdi)\n",(int)(((char*)&(s->w_size))-((char*)s))); +printf("#define dsWMask (%3u)(%%rdi)\n",(int)(((char*)&(s->w_mask))-((char*)s))); +printf("#define dsWindow (%3u)(%%rdi)\n",(int)(((char*)&(s->window))-((char*)s))); +printf("#define dsPrev (%3u)(%%rdi)\n",(int)(((char*)&(s->prev))-((char*)s))); +printf("#define dsMatchLen (%3u)(%%rdi)\n",(int)(((char*)&(s->match_length))-((char*)s))); +printf("#define dsPrevMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_match))-((char*)s))); +printf("#define dsStrStart (%3u)(%%rdi)\n",(int)(((char*)&(s->strstart))-((char*)s))); +printf("#define dsMatchStart (%3u)(%%rdi)\n",(int)(((char*)&(s->match_start))-((char*)s))); +printf("#define dsLookahead (%3u)(%%rdi)\n",(int)(((char*)&(s->lookahead))-((char*)s))); +printf("#define dsPrevLen (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_length))-((char*)s))); +printf("#define dsMaxChainLen (%3u)(%%rdi)\n",(int)(((char*)&(s->max_chain_length))-((char*)s))); +printf("#define dsGoodMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->good_match))-((char*)s))); +printf("#define dsNiceMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->nice_match))-((char*)s))); +} + +*/ + + +/* + to compile for XCode 3.2 on MacOSX x86_64 + - run "gcc -g -c -DXCODE_MAC_X64_STRUCTURE amd64-match.S" + */ + + +#ifndef CURRENT_LINX_XCODE_MAC_X64_STRUCTURE +#define dsWSize ( 68)(%rdi) +#define dsWMask ( 76)(%rdi) +#define dsWindow ( 80)(%rdi) +#define dsPrev ( 96)(%rdi) +#define dsMatchLen (144)(%rdi) +#define dsPrevMatch (148)(%rdi) +#define dsStrStart (156)(%rdi) +#define dsMatchStart (160)(%rdi) +#define dsLookahead (164)(%rdi) +#define dsPrevLen (168)(%rdi) +#define dsMaxChainLen (172)(%rdi) +#define dsGoodMatch (188)(%rdi) +#define dsNiceMatch (192)(%rdi) + +#else + +#ifndef STRUCT_OFFSET +# define STRUCT_OFFSET (0) +#endif + + +#define dsWSize ( 56 + STRUCT_OFFSET)(%rdi) +#define dsWMask ( 64 + STRUCT_OFFSET)(%rdi) +#define dsWindow ( 72 + STRUCT_OFFSET)(%rdi) +#define dsPrev ( 88 + STRUCT_OFFSET)(%rdi) +#define dsMatchLen (136 + STRUCT_OFFSET)(%rdi) +#define dsPrevMatch (140 + STRUCT_OFFSET)(%rdi) +#define dsStrStart (148 + STRUCT_OFFSET)(%rdi) +#define dsMatchStart (152 + STRUCT_OFFSET)(%rdi) +#define dsLookahead (156 + STRUCT_OFFSET)(%rdi) +#define dsPrevLen (160 + STRUCT_OFFSET)(%rdi) +#define dsMaxChainLen (164 + STRUCT_OFFSET)(%rdi) +#define dsGoodMatch (180 + STRUCT_OFFSET)(%rdi) +#define dsNiceMatch (184 + STRUCT_OFFSET)(%rdi) + +#endif + + + + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ + +longest_match: +/* + * Retrieve the function arguments. %curmatch will hold cur_match + * throughout the entire function (passed via rsi on amd64). + * rdi will hold the pointer to the deflate_state (first arg on amd64) + */ + mov %rsi, save_rsi + mov %rbx, save_rbx + mov %r12, save_r12 + mov %r13, save_r13 + mov %r14, save_r14 + mov %r15, save_r15 + +/* uInt wmask = s->w_mask; */ +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen, %eax + movl dsGoodMatch, %ebx + cmpl %ebx, %eax + movl dsWMask, %eax + movl dsMaxChainLen, %chainlenwmask + jl LastMatchGood + shrl $2, %chainlenwmask +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the wmask */ +/* value, which it will always accompany. */ + + decl %chainlenwmask + shll $16, %chainlenwmask + orl %eax, %chainlenwmask + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch, %eax + movl dsLookahead, %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, %nicematch + +/* register Bytef *scan = s->window + s->strstart; */ + + mov dsWindow, %window + movl dsStrStart, %limitd + lea (%limit, %window), %scan + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + mov %scan, %scanalign + negl %scanalignd + andl $3, %scanalignd + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize, %eax + subl $MIN_LOOKAHEAD, %eax + xorl %ecx, %ecx + subl %eax, %limitd + cmovng %ecx, %limitd + +/* int best_len = s->prev_length; */ + + movl dsPrevLen, %bestlend + +/* Store the sum of s->window + best_len in %windowbestlen locally, and in memory. */ + + lea (%window, %bestlen), %windowbestlen + mov %windowbestlen, _windowbestlen + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ +/* Posf *prev = s->prev; */ + + movzwl (%scan), %scanstart + movzwl -1(%scan, %bestlen), %scanend + mov dsPrev, %prev + +/* Jump into the main loop. */ + + movl %chainlenwmask, _chainlenwmask + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + */ +LookupLoop: + andl %chainlenwmask, %curmatchd + movzwl (%prev, %curmatch, 2), %curmatchd + cmpl %limitd, %curmatchd + jbe LeaveNow + subl $0x00010000, %chainlenwmask + js LeaveNow +LoopEntry: cmpw -1(%windowbestlen, %curmatch), %scanendw + jne LookupLoop + cmpw %scanstartw, (%window, %curmatch) + jne LookupLoop + +/* Store the current value of chainlen. */ + movl %chainlenwmask, _chainlenwmask + +/* %scan is the string under scrutiny, and %prev to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + mov $(-MAX_MATCH_8), %rdx + lea (%curmatch, %window), %windowbestlen + lea MAX_MATCH_8(%windowbestlen, %scanalign), %windowbestlen + lea MAX_MATCH_8(%scan, %scanalign), %prev + +/* the prefetching below makes very little difference... */ + prefetcht1 (%windowbestlen, %rdx) + prefetcht1 (%prev, %rdx) + +/* + * Test the strings for equality, 8 bytes at a time. At the end, + * adjust %rdx so that it is offset to the exact byte that mismatched. + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance -- unrolling it, for example, makes no difference. + */ + +#undef USE_SSE /* works, but is 6-7% slower, than non-SSE... */ + +LoopCmps: +#ifdef USE_SSE + /* Preload the SSE registers */ + movdqu (%windowbestlen, %rdx), %xmm1 + movdqu (%prev, %rdx), %xmm2 + pcmpeqb %xmm2, %xmm1 + movdqu 16(%windowbestlen, %rdx), %xmm3 + movdqu 16(%prev, %rdx), %xmm4 + pcmpeqb %xmm4, %xmm3 + movdqu 32(%windowbestlen, %rdx), %xmm5 + movdqu 32(%prev, %rdx), %xmm6 + pcmpeqb %xmm6, %xmm5 + movdqu 48(%windowbestlen, %rdx), %xmm7 + movdqu 48(%prev, %rdx), %xmm8 + pcmpeqb %xmm8, %xmm7 + + /* Check the comparisions' results */ + pmovmskb %xmm1, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + /* this is the only iteration of the loop with a possibility of having + incremented rdx by 0x108 (each loop iteration add 16*4 = 0x40 + and (0x40*4)+8=0x108 */ + add $8, %rdx + jz LenMaximum + add $8, %rdx + + + pmovmskb %xmm3, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + + add $16, %rdx + + + pmovmskb %xmm5, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + add $16, %rdx + + + pmovmskb %xmm7, %rax + notw %ax + bsfw %ax, %ax + jnz LeaveLoopCmps + + add $16, %rdx + + jmp LoopCmps +LeaveLoopCmps: add %rax, %rdx +#else + mov (%windowbestlen, %rdx), %rax + xor (%prev, %rdx), %rax + jnz LeaveLoopCmps + + mov 8(%windowbestlen, %rdx), %rax + xor 8(%prev, %rdx), %rax + jnz LeaveLoopCmps8 + + mov 16(%windowbestlen, %rdx), %rax + xor 16(%prev, %rdx), %rax + jnz LeaveLoopCmps16 + + add $24, %rdx + jnz LoopCmps + jmp LenMaximum +# if 0 +/* + * This three-liner is tantalizingly simple, but bsf is a slow instruction, + * and the complicated alternative down below is quite a bit faster. Sad... + */ + +LeaveLoopCmps: bsf %rax, %rax /* find the first non-zero bit */ + shrl $3, %eax /* divide by 8 to get the byte */ + add %rax, %rdx +# else +LeaveLoopCmps16: + add $8, %rdx +LeaveLoopCmps8: + add $8, %rdx +LeaveLoopCmps: testl $0xFFFFFFFF, %eax /* Check the first 4 bytes */ + jnz Check16 + add $4, %rdx + shr $32, %rax +Check16: testw $0xFFFF, %ax + jnz LenLower + add $2, %rdx + shrl $16, %eax +LenLower: subb $1, %al + adc $0, %rdx +# endif +#endif + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%prev, %rdx), %rax + sub %scan, %rax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + cmpl %bestlend, %eax + jg LongerMatch + mov _windowbestlen, %windowbestlen + mov dsPrev, %prev + movl _chainlenwmask, %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: + movl %eax, %bestlend + movl %curmatchd, dsMatchStart + cmpl %nicematch, %eax + jge LeaveNow + + lea (%window, %bestlen), %windowbestlen + mov %windowbestlen, _windowbestlen + + movzwl -1(%scan, %rax), %scanend + mov dsPrev, %prev + movl _chainlenwmask, %chainlenwmask + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: + movl $MAX_MATCH, %bestlend + movl %curmatchd, dsMatchStart + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl dsLookahead, %eax + cmpl %eax, %bestlend + cmovngl %bestlend, %eax +LookaheadRet: + +/* Restore the registers and return from whence we came. */ + + mov save_rsi, %rsi + mov save_rbx, %rbx + mov save_r12, %r12 + mov save_r13, %r13 + mov save_r14, %r14 + mov save_r15, %r15 + + ret + +match_init: ret diff --git a/libz/contrib/asm686/README.686 b/libz/contrib/asm686/README.686 new file mode 100644 index 000000000..a0bf3bea4 --- /dev/null +++ b/libz/contrib/asm686/README.686 @@ -0,0 +1,51 @@ +This is a patched version of zlib, modified to use +Pentium-Pro-optimized assembly code in the deflation algorithm. The +files changed/added by this patch are: + +README.686 +match.S + +The speedup that this patch provides varies, depending on whether the +compiler used to build the original version of zlib falls afoul of the +PPro's speed traps. My own tests show a speedup of around 10-20% at +the default compression level, and 20-30% using -9, against a version +compiled using gcc 2.7.2.3. Your mileage may vary. + +Note that this code has been tailored for the PPro/PII in particular, +and will not perform particuarly well on a Pentium. + +If you are using an assembler other than GNU as, you will have to +translate match.S to use your assembler's syntax. (Have fun.) + +Brian Raiter +breadbox@muppetlabs.com +April, 1998 + + +Added for zlib 1.1.3: + +The patches come from +http://www.muppetlabs.com/~breadbox/software/assembly.html + +To compile zlib with this asm file, copy match.S to the zlib directory +then do: + +CFLAGS="-O3 -DASMV" ./configure +make OBJA=match.o + + +Update: + +I've been ignoring these assembly routines for years, believing that +gcc's generated code had caught up with it sometime around gcc 2.95 +and the major rearchitecting of the Pentium 4. However, I recently +learned that, despite what I believed, this code still has some life +in it. On the Pentium 4 and AMD64 chips, it continues to run about 8% +faster than the code produced by gcc 4.1. + +In acknowledgement of its continuing usefulness, I've altered the +license to match that of the rest of zlib. Share and Enjoy! + +Brian Raiter +breadbox@muppetlabs.com +April, 2007 diff --git a/libz/contrib/asm686/match.S b/libz/contrib/asm686/match.S new file mode 100644 index 000000000..fa4210927 --- /dev/null +++ b/libz/contrib/asm686/match.S @@ -0,0 +1,357 @@ +/* match.S -- x86 assembly version of the zlib longest_match() function. + * Optimized for the Intel 686 chips (PPro and later). + * + * Copyright (C) 1998, 2007 Brian Raiter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the author be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef NO_UNDERLINE +#define match_init _match_init +#define longest_match _longest_match +#endif + +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ + +#define chainlenwmask 0 /* high word: current chain len */ + /* low word: s->wmask */ +#define window 4 /* local copy of s->window */ +#define windowbestlen 8 /* s->window + bestlen */ +#define scanstart 16 /* first two bytes of string */ +#define scanend 12 /* last two bytes of string */ +#define scanalign 20 /* dword-misalignment of string */ +#define nicematch 24 /* a good enough match size */ +#define bestlen 28 /* size of best match so far */ +#define scan 32 /* ptr to string wanting match */ + +#define LocalVarsSize (36) +/* saved ebx 36 */ +/* saved edi 40 */ +/* saved esi 44 */ +/* saved ebp 48 */ +/* return address 52 */ +#define deflatestate 56 /* the function arguments */ +#define curmatch 60 + +/* All the +zlib1222add offsets are due to the addition of fields + * in zlib in the deflate_state structure since the asm code was first written + * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). + * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). + * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + */ + +#define zlib1222add (8) + +#define dsWSize (36+zlib1222add) +#define dsWMask (44+zlib1222add) +#define dsWindow (48+zlib1222add) +#define dsPrev (56+zlib1222add) +#define dsMatchLen (88+zlib1222add) +#define dsPrevMatch (92+zlib1222add) +#define dsStrStart (100+zlib1222add) +#define dsMatchStart (104+zlib1222add) +#define dsLookahead (108+zlib1222add) +#define dsPrevLen (112+zlib1222add) +#define dsMaxChainLen (116+zlib1222add) +#define dsGoodMatch (132+zlib1222add) +#define dsNiceMatch (136+zlib1222add) + + +.file "match.S" + +.globl match_init, longest_match + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ +.cfi_sections .debug_frame + +longest_match: + +.cfi_startproc +/* Save registers that the compiler may be using, and adjust %esp to */ +/* make room for our stack frame. */ + + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset ebp, -8 + pushl %edi + .cfi_def_cfa_offset 12 + pushl %esi + .cfi_def_cfa_offset 16 + pushl %ebx + .cfi_def_cfa_offset 20 + subl $LocalVarsSize, %esp + .cfi_def_cfa_offset LocalVarsSize+20 + +/* Retrieve the function arguments. %ecx will hold cur_match */ +/* throughout the entire function. %edx will hold the pointer to the */ +/* deflate_state structure during the function's setup (before */ +/* entering the main loop). */ + + movl deflatestate(%esp), %edx + movl curmatch(%esp), %ecx + +/* uInt wmask = s->w_mask; */ +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen(%edx), %eax + movl dsGoodMatch(%edx), %ebx + cmpl %ebx, %eax + movl dsWMask(%edx), %eax + movl dsMaxChainLen(%edx), %ebx + jl LastMatchGood + shrl $2, %ebx +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the wmask */ +/* value, which it will always accompany. */ + + decl %ebx + shll $16, %ebx + orl %eax, %ebx + movl %ebx, chainlenwmask(%esp) + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch(%edx), %eax + movl dsLookahead(%edx), %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, nicematch(%esp) + +/* register Bytef *scan = s->window + s->strstart; */ + + movl dsWindow(%edx), %esi + movl %esi, window(%esp) + movl dsStrStart(%edx), %ebp + lea (%esi,%ebp), %edi + movl %edi, scan(%esp) + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + movl %edi, %eax + negl %eax + andl $3, %eax + movl %eax, scanalign(%esp) + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize(%edx), %eax + subl $MIN_LOOKAHEAD, %eax + subl %eax, %ebp + jg LimitPositive + xorl %ebp, %ebp +LimitPositive: + +/* int best_len = s->prev_length; */ + + movl dsPrevLen(%edx), %eax + movl %eax, bestlen(%esp) + +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ + + addl %eax, %esi + movl %esi, windowbestlen(%esp) + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ +/* Posf *prev = s->prev; */ + + movzwl (%edi), %ebx + movl %ebx, scanstart(%esp) + movzwl -1(%edi,%eax), %ebx + movl %ebx, scanend(%esp) + movl dsPrev(%edx), %edi + +/* Jump into the main loop. */ + + movl chainlenwmask(%esp), %edx + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + * + * Within this loop: + * %ebx = scanend + * %ecx = curmatch + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) + * %esi = windowbestlen - i.e., (window + bestlen) + * %edi = prev + * %ebp = limit + */ +LookupLoop: + andl %edx, %ecx + movzwl (%edi,%ecx,2), %ecx + cmpl %ebp, %ecx + jbe LeaveNow + subl $0x00010000, %edx + js LeaveNow +LoopEntry: movzwl -1(%esi,%ecx), %eax + cmpl %ebx, %eax + jnz LookupLoop + movl window(%esp), %eax + movzwl (%eax,%ecx), %eax + cmpl scanstart(%esp), %eax + jnz LookupLoop + +/* Store the current value of chainlen. */ + + movl %edx, chainlenwmask(%esp) + +/* Point %edi to the string under scrutiny, and %esi to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + movl window(%esp), %esi + movl scan(%esp), %edi + addl %ecx, %esi + movl scanalign(%esp), %eax + movl $(-MAX_MATCH_8), %edx + lea MAX_MATCH_8(%edi,%eax), %edi + lea MAX_MATCH_8(%esi,%eax), %esi + +/* Test the strings for equality, 8 bytes at a time. At the end, + * adjust %edx so that it is offset to the exact byte that mismatched. + * + * We already know at this point that the first three bytes of the + * strings match each other, and they can be safely passed over before + * starting the compare loop. So what this code does is skip over 0-3 + * bytes, as much as necessary in order to dword-align the %edi + * pointer. (%esi will still be misaligned three times out of four.) + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance. + */ +LoopCmps: + movl (%esi,%edx), %eax + xorl (%edi,%edx), %eax + jnz LeaveLoopCmps + movl 4(%esi,%edx), %eax + xorl 4(%edi,%edx), %eax + jnz LeaveLoopCmps4 + addl $8, %edx + jnz LoopCmps + jmp LenMaximum +LeaveLoopCmps4: addl $4, %edx +LeaveLoopCmps: testl $0x0000FFFF, %eax + jnz LenLower + addl $2, %edx + shrl $16, %eax +LenLower: subb $1, %al + adcl $0, %edx + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%edi,%edx), %eax + movl scan(%esp), %edi + subl %edi, %eax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + cmpl %ebx, %eax + jg LongerMatch + movl windowbestlen(%esp), %esi + movl dsPrev(%edx), %edi + movl scanend(%esp), %ebx + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: movl nicematch(%esp), %ebx + movl %eax, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + cmpl %ebx, %eax + jge LeaveNow + movl window(%esp), %esi + addl %eax, %esi + movl %esi, windowbestlen(%esp) + movzwl -1(%edi,%eax), %ebx + movl dsPrev(%edx), %edi + movl %ebx, scanend(%esp) + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: movl deflatestate(%esp), %edx + movl $MAX_MATCH, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + movl dsLookahead(%edx), %eax + cmpl %eax, %ebx + jg LookaheadRet + movl %ebx, %eax +LookaheadRet: + +/* Restore the stack and return from whence we came. */ + + addl $LocalVarsSize, %esp + .cfi_def_cfa_offset 20 + popl %ebx + .cfi_def_cfa_offset 16 + popl %esi + .cfi_def_cfa_offset 12 + popl %edi + .cfi_def_cfa_offset 8 + popl %ebp + .cfi_def_cfa_offset 4 +.cfi_endproc +match_init: ret diff --git a/libz/contrib/blast/README b/libz/contrib/blast/README new file mode 100644 index 000000000..e3a60b3f5 --- /dev/null +++ b/libz/contrib/blast/README @@ -0,0 +1,4 @@ +Read blast.h for purpose and usage. + +Mark Adler +madler@alumni.caltech.edu diff --git a/libz/contrib/blast/blast.c b/libz/contrib/blast/blast.c new file mode 100644 index 000000000..69ef0fe00 --- /dev/null +++ b/libz/contrib/blast/blast.c @@ -0,0 +1,446 @@ +/* blast.c + * Copyright (C) 2003, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in blast.h + * version 1.2, 24 Oct 2012 + * + * blast.c decompresses data compressed by the PKWare Compression Library. + * This function provides functionality similar to the explode() function of + * the PKWare library, hence the name "blast". + * + * This decompressor is based on the excellent format description provided by + * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the + * example Ben provided in the post is incorrect. The distance 110001 should + * instead be 111000. When corrected, the example byte stream becomes: + * + * 00 04 82 24 25 8f 80 7f + * + * which decompresses to "AIAIAIAIAIAIA" (without the quotes). + */ + +/* + * Change history: + * + * 1.0 12 Feb 2003 - First version + * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data + * 1.2 24 Oct 2012 - Add note about using binary mode in stdio + * - Fix comparisons of differently signed integers + */ + +#include /* for setjmp(), longjmp(), and jmp_buf */ +#include "blast.h" /* prototype for blast() */ + +#define local static /* for local function definitions */ +#define MAXBITS 13 /* maximum code length */ +#define MAXWIN 4096 /* maximum window size */ + +/* input and output state */ +struct state { + /* input state */ + blast_in infun; /* input function provided by user */ + void *inhow; /* opaque information passed to infun() */ + unsigned char *in; /* next input location */ + unsigned left; /* available input at in */ + int bitbuf; /* bit buffer */ + int bitcnt; /* number of bits in bit buffer */ + + /* input limit error return state for bits() and decode() */ + jmp_buf env; + + /* output state */ + blast_out outfun; /* output function provided by user */ + void *outhow; /* opaque information passed to outfun() */ + unsigned next; /* index of next write location in out[] */ + int first; /* true to check distances (for first 4K) */ + unsigned char out[MAXWIN]; /* output buffer and sliding window */ +}; + +/* + * Return need bits from the input stream. This always leaves less than + * eight bits in the buffer. bits() works properly for need == 0. + * + * Format notes: + * + * - Bits are stored in bytes from the least significant bit to the most + * significant bit. Therefore bits are dropped from the bottom of the bit + * buffer, using shift right, and new bytes are appended to the top of the + * bit buffer, using shift left. + */ +local int bits(struct state *s, int need) +{ + int val; /* bit accumulator */ + + /* load at least need bits into val */ + val = s->bitbuf; + while (s->bitcnt < need) { + if (s->left == 0) { + s->left = s->infun(s->inhow, &(s->in)); + if (s->left == 0) longjmp(s->env, 1); /* out of input */ + } + val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */ + s->left--; + s->bitcnt += 8; + } + + /* drop need bits and update buffer, always zero to seven bits left */ + s->bitbuf = val >> need; + s->bitcnt -= need; + + /* return need bits, zeroing the bits above that */ + return val & ((1 << need) - 1); +} + +/* + * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of + * each length, which for a canonical code are stepped through in order. + * symbol[] are the symbol values in canonical order, where the number of + * entries is the sum of the counts in count[]. The decoding process can be + * seen in the function decode() below. + */ +struct huffman { + short *count; /* number of symbols of each length */ + short *symbol; /* canonically ordered symbols */ +}; + +/* + * Decode a code from the stream s using huffman table h. Return the symbol or + * a negative value if there is an error. If all of the lengths are zero, i.e. + * an empty code, or if the code is incomplete and an invalid code is received, + * then -9 is returned after reading MAXBITS bits. + * + * Format notes: + * + * - The codes as stored in the compressed data are bit-reversed relative to + * a simple integer ordering of codes of the same lengths. Hence below the + * bits are pulled from the compressed data one at a time and used to + * build the code value reversed from what is in the stream in order to + * permit simple integer comparisons for decoding. + * + * - The first code for the shortest length is all ones. Subsequent codes of + * the same length are simply integer decrements of the previous code. When + * moving up a length, a one bit is appended to the code. For a complete + * code, the last code of the longest length will be all zeros. To support + * this ordering, the bits pulled during decoding are inverted to apply the + * more "natural" ordering starting with all zeros and incrementing. + */ +local int decode(struct state *s, struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + int bitbuf; /* bits from stream */ + int left; /* bits left in next or left to process */ + short *next; /* next number of codes */ + + bitbuf = s->bitbuf; + left = s->bitcnt; + code = first = index = 0; + len = 1; + next = h->count + 1; + while (1) { + while (left--) { + code |= (bitbuf & 1) ^ 1; /* invert code */ + bitbuf >>= 1; + count = *next++; + if (code < first + count) { /* if length len, return symbol */ + s->bitbuf = bitbuf; + s->bitcnt = (s->bitcnt - len) & 7; + return h->symbol[index + (code - first)]; + } + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + len++; + } + left = (MAXBITS+1) - len; + if (left == 0) break; + if (s->left == 0) { + s->left = s->infun(s->inhow, &(s->in)); + if (s->left == 0) longjmp(s->env, 1); /* out of input */ + } + bitbuf = *(s->in)++; + s->left--; + if (left > 8) left = 8; + } + return -9; /* ran out of codes */ +} + +/* + * Given a list of repeated code lengths rep[0..n-1], where each byte is a + * count (high four bits + 1) and a code length (low four bits), generate the + * list of code lengths. This compaction reduces the size of the object code. + * Then given the list of code lengths length[0..n-1] representing a canonical + * Huffman code for n symbols, construct the tables required to decode those + * codes. Those tables are the number of codes of each length, and the symbols + * sorted by length, retaining their original order within each length. The + * return value is zero for a complete code set, negative for an over- + * subscribed code set, and positive for an incomplete code set. The tables + * can be used if the return value is zero or positive, but they cannot be used + * if the return value is negative. If the return value is zero, it is not + * possible for decode() using that table to return an error--any stream of + * enough bits will resolve to a symbol. If the return value is positive, then + * it is possible for decode() using that table to return an error for received + * codes past the end of the incomplete lengths. + */ +local int construct(struct huffman *h, const unsigned char *rep, int n) +{ + int symbol; /* current symbol when stepping through length[] */ + int len; /* current length when stepping through h->count[] */ + int left; /* number of possible codes left of current length */ + short offs[MAXBITS+1]; /* offsets in symbol table for each length */ + short length[256]; /* code lengths */ + + /* convert compact repeat counts into symbol bit length list */ + symbol = 0; + do { + len = *rep++; + left = (len >> 4) + 1; + len &= 15; + do { + length[symbol++] = len; + } while (--left); + } while (--n); + n = symbol; + + /* count number of codes of each length */ + for (len = 0; len <= MAXBITS; len++) + h->count[len] = 0; + for (symbol = 0; symbol < n; symbol++) + (h->count[length[symbol]])++; /* assumes lengths are within bounds */ + if (h->count[0] == n) /* no codes! */ + return 0; /* complete, but decode() will fail */ + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; /* one possible code of zero length */ + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; /* one more bit, double codes left */ + left -= h->count[len]; /* deduct count from possible codes */ + if (left < 0) return left; /* over-subscribed--return negative */ + } /* left > 0 means incomplete */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + h->count[len]; + + /* + * put symbols in table sorted by length, by symbol order within each + * length + */ + for (symbol = 0; symbol < n; symbol++) + if (length[symbol] != 0) + h->symbol[offs[length[symbol]]++] = symbol; + + /* return zero for complete set, positive for incomplete set */ + return left; +} + +/* + * Decode PKWare Compression Library stream. + * + * Format notes: + * + * - First byte is 0 if literals are uncoded or 1 if they are coded. Second + * byte is 4, 5, or 6 for the number of extra bits in the distance code. + * This is the base-2 logarithm of the dictionary size minus six. + * + * - Compressed data is a combination of literals and length/distance pairs + * terminated by an end code. Literals are either Huffman coded or + * uncoded bytes. A length/distance pair is a coded length followed by a + * coded distance to represent a string that occurs earlier in the + * uncompressed data that occurs again at the current location. + * + * - A bit preceding a literal or length/distance pair indicates which comes + * next, 0 for literals, 1 for length/distance. + * + * - If literals are uncoded, then the next eight bits are the literal, in the + * normal bit order in th stream, i.e. no bit-reversal is needed. Similarly, + * no bit reversal is needed for either the length extra bits or the distance + * extra bits. + * + * - Literal bytes are simply written to the output. A length/distance pair is + * an instruction to copy previously uncompressed bytes to the output. The + * copy is from distance bytes back in the output stream, copying for length + * bytes. + * + * - Distances pointing before the beginning of the output data are not + * permitted. + * + * - Overlapped copies, where the length is greater than the distance, are + * allowed and common. For example, a distance of one and a length of 518 + * simply copies the last byte 518 times. A distance of four and a length of + * twelve copies the last four bytes three times. A simple forward copy + * ignoring whether the length is greater than the distance or not implements + * this correctly. + */ +local int decomp(struct state *s) +{ + int lit; /* true if literals are coded */ + int dict; /* log2(dictionary size) - 6 */ + int symbol; /* decoded symbol, extra bits for distance */ + int len; /* length for copy */ + unsigned dist; /* distance for copy */ + int copy; /* copy counter */ + unsigned char *from, *to; /* copy pointers */ + static int virgin = 1; /* build tables once */ + static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */ + static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */ + static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */ + static struct huffman litcode = {litcnt, litsym}; /* length code */ + static struct huffman lencode = {lencnt, lensym}; /* length code */ + static struct huffman distcode = {distcnt, distsym};/* distance code */ + /* bit lengths of literal codes */ + static const unsigned char litlen[] = { + 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8, + 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5, + 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12, + 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27, + 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45, + 44, 173}; + /* bit lengths of length codes 0..15 */ + static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23}; + /* bit lengths of distance codes 0..63 */ + static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248}; + static const short base[16] = { /* base for length codes */ + 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264}; + static const char extra[16] = { /* extra bits for length codes */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8}; + + /* set up decoding tables (once--might not be thread-safe) */ + if (virgin) { + construct(&litcode, litlen, sizeof(litlen)); + construct(&lencode, lenlen, sizeof(lenlen)); + construct(&distcode, distlen, sizeof(distlen)); + virgin = 0; + } + + /* read header */ + lit = bits(s, 8); + if (lit > 1) return -1; + dict = bits(s, 8); + if (dict < 4 || dict > 6) return -2; + + /* decode literals and length/distance pairs */ + do { + if (bits(s, 1)) { + /* get length */ + symbol = decode(s, &lencode); + len = base[symbol] + bits(s, extra[symbol]); + if (len == 519) break; /* end code */ + + /* get distance */ + symbol = len == 2 ? 2 : dict; + dist = decode(s, &distcode) << symbol; + dist += bits(s, symbol); + dist++; + if (s->first && dist > s->next) + return -3; /* distance too far back */ + + /* copy length bytes from distance bytes back */ + do { + to = s->out + s->next; + from = to - dist; + copy = MAXWIN; + if (s->next < dist) { + from += copy; + copy = dist; + } + copy -= s->next; + if (copy > len) copy = len; + len -= copy; + s->next += copy; + do { + *to++ = *from++; + } while (--copy); + if (s->next == MAXWIN) { + if (s->outfun(s->outhow, s->out, s->next)) return 1; + s->next = 0; + s->first = 0; + } + } while (len != 0); + } + else { + /* get literal and write it */ + symbol = lit ? decode(s, &litcode) : bits(s, 8); + s->out[s->next++] = symbol; + if (s->next == MAXWIN) { + if (s->outfun(s->outhow, s->out, s->next)) return 1; + s->next = 0; + s->first = 0; + } + } + } while (1); + return 0; +} + +/* See comments in blast.h */ +int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow) +{ + struct state s; /* input/output state */ + int err; /* return value */ + + /* initialize input state */ + s.infun = infun; + s.inhow = inhow; + s.left = 0; + s.bitbuf = 0; + s.bitcnt = 0; + + /* initialize output state */ + s.outfun = outfun; + s.outhow = outhow; + s.next = 0; + s.first = 1; + + /* return if bits() or decode() tries to read past available input */ + if (setjmp(s.env) != 0) /* if came back here via longjmp(), */ + err = 2; /* then skip decomp(), return error */ + else + err = decomp(&s); /* decompress */ + + /* write any leftover output and update the error code if needed */ + if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0) + err = 1; + return err; +} + +#ifdef TEST +/* Example of how to use blast() */ +#include +#include + +#define CHUNK 16384 + +local unsigned inf(void *how, unsigned char **buf) +{ + static unsigned char hold[CHUNK]; + + *buf = hold; + return fread(hold, 1, CHUNK, (FILE *)how); +} + +local int outf(void *how, unsigned char *buf, unsigned len) +{ + return fwrite(buf, 1, len, (FILE *)how) != len; +} + +/* Decompress a PKWare Compression Library stream from stdin to stdout */ +int main(void) +{ + int ret, n; + + /* decompress to stdout */ + ret = blast(inf, stdin, outf, stdout); + if (ret != 0) fprintf(stderr, "blast error: %d\n", ret); + + /* see if there are any leftover bytes */ + n = 0; + while (getchar() != EOF) n++; + if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n); + + /* return blast() error code */ + return ret; +} +#endif diff --git a/libz/contrib/blast/blast.h b/libz/contrib/blast/blast.h new file mode 100644 index 000000000..658cfd320 --- /dev/null +++ b/libz/contrib/blast/blast.h @@ -0,0 +1,75 @@ +/* blast.h -- interface for blast.c + Copyright (C) 2003, 2012 Mark Adler + version 1.2, 24 Oct 2012 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + + +/* + * blast() decompresses the PKWare Data Compression Library (DCL) compressed + * format. It provides the same functionality as the explode() function in + * that library. (Note: PKWare overused the "implode" verb, and the format + * used by their library implode() function is completely different and + * incompatible with the implode compression method supported by PKZIP.) + * + * The binary mode for stdio functions should be used to assure that the + * compressed data is not corrupted when read or written. For example: + * fopen(..., "rb") and fopen(..., "wb"). + */ + + +typedef unsigned (*blast_in)(void *how, unsigned char **buf); +typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len); +/* Definitions for input/output functions passed to blast(). See below for + * what the provided functions need to do. + */ + + +int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow); +/* Decompress input to output using the provided infun() and outfun() calls. + * On success, the return value of blast() is zero. If there is an error in + * the source data, i.e. it is not in the proper format, then a negative value + * is returned. If there is not enough input available or there is not enough + * output space, then a positive error is returned. + * + * The input function is invoked: len = infun(how, &buf), where buf is set by + * infun() to point to the input buffer, and infun() returns the number of + * available bytes there. If infun() returns zero, then blast() returns with + * an input error. (blast() only asks for input if it needs it.) inhow is for + * use by the application to pass an input descriptor to infun(), if desired. + * + * The output function is invoked: err = outfun(how, buf, len), where the bytes + * to be written are buf[0..len-1]. If err is not zero, then blast() returns + * with an output error. outfun() is always called with len <= 4096. outhow + * is for use by the application to pass an output descriptor to outfun(), if + * desired. + * + * The return codes are: + * + * 2: ran out of input before completing decompression + * 1: output error before completing decompression + * 0: successful decompression + * -1: literal flag not zero or one + * -2: dictionary size not in 4..6 + * -3: distance is too far back + * + * At the bottom of blast.c is an example program that uses blast() that can be + * compiled to produce a command-line decompression filter by defining TEST. + */ diff --git a/libz/contrib/blast/test.txt b/libz/contrib/blast/test.txt new file mode 100644 index 000000000..bfdf1c5dc --- /dev/null +++ b/libz/contrib/blast/test.txt @@ -0,0 +1 @@ +AIAIAIAIAIAIA \ No newline at end of file diff --git a/libz/contrib/delphi/ZLib.pas b/libz/contrib/delphi/ZLib.pas new file mode 100644 index 000000000..a579974f0 --- /dev/null +++ b/libz/contrib/delphi/ZLib.pas @@ -0,0 +1,557 @@ +{*******************************************************} +{ } +{ Borland Delphi Supplemental Components } +{ ZLIB Data Compression Interface Unit } +{ } +{ Copyright (c) 1997,99 Borland Corporation } +{ } +{*******************************************************} + +{ Updated for zlib 1.2.x by Cosmin Truta } + +unit ZLib; + +interface + +uses SysUtils, Classes; + +type + TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl; + TFree = procedure (AppData, Block: Pointer); cdecl; + + // Internal structure. Ignore. + TZStreamRec = packed record + next_in: PChar; // next input byte + avail_in: Integer; // number of bytes available at next_in + total_in: Longint; // total nb of input bytes read so far + + next_out: PChar; // next output byte should be put here + avail_out: Integer; // remaining free space at next_out + total_out: Longint; // total nb of bytes output so far + + msg: PChar; // last error message, NULL if no error + internal: Pointer; // not visible by applications + + zalloc: TAlloc; // used to allocate the internal state + zfree: TFree; // used to free the internal state + AppData: Pointer; // private data object passed to zalloc and zfree + + data_type: Integer; // best guess about the data type: ascii or binary + adler: Longint; // adler32 value of the uncompressed data + reserved: Longint; // reserved for future use + end; + + // Abstract ancestor class + TCustomZlibStream = class(TStream) + private + FStrm: TStream; + FStrmPos: Integer; + FOnProgress: TNotifyEvent; + FZRec: TZStreamRec; + FBuffer: array [Word] of Char; + protected + procedure Progress(Sender: TObject); dynamic; + property OnProgress: TNotifyEvent read FOnProgress write FOnProgress; + constructor Create(Strm: TStream); + end; + +{ TCompressionStream compresses data on the fly as data is written to it, and + stores the compressed data to another stream. + + TCompressionStream is write-only and strictly sequential. Reading from the + stream will raise an exception. Using Seek to move the stream pointer + will raise an exception. + + Output data is cached internally, written to the output stream only when + the internal output buffer is full. All pending output data is flushed + when the stream is destroyed. + + The Position property returns the number of uncompressed bytes of + data that have been written to the stream so far. + + CompressionRate returns the on-the-fly percentage by which the original + data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100 + If raw data size = 100 and compressed data size = 25, the CompressionRate + is 75% + + The OnProgress event is called each time the output buffer is filled and + written to the output stream. This is useful for updating a progress + indicator when you are writing a large chunk of data to the compression + stream in a single call.} + + + TCompressionLevel = (clNone, clFastest, clDefault, clMax); + + TCompressionStream = class(TCustomZlibStream) + private + function GetCompressionRate: Single; + public + constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream); + destructor Destroy; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + function Seek(Offset: Longint; Origin: Word): Longint; override; + property CompressionRate: Single read GetCompressionRate; + property OnProgress; + end; + +{ TDecompressionStream decompresses data on the fly as data is read from it. + + Compressed data comes from a separate source stream. TDecompressionStream + is read-only and unidirectional; you can seek forward in the stream, but not + backwards. The special case of setting the stream position to zero is + allowed. Seeking forward decompresses data until the requested position in + the uncompressed data has been reached. Seeking backwards, seeking relative + to the end of the stream, requesting the size of the stream, and writing to + the stream will raise an exception. + + The Position property returns the number of bytes of uncompressed data that + have been read from the stream so far. + + The OnProgress event is called each time the internal input buffer of + compressed data is exhausted and the next block is read from the input stream. + This is useful for updating a progress indicator when you are reading a + large chunk of data from the decompression stream in a single call.} + + TDecompressionStream = class(TCustomZlibStream) + public + constructor Create(Source: TStream); + destructor Destroy; override; + function Read(var Buffer; Count: Longint): Longint; override; + function Write(const Buffer; Count: Longint): Longint; override; + function Seek(Offset: Longint; Origin: Word): Longint; override; + property OnProgress; + end; + + + +{ CompressBuf compresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + Out: OutBuf = ptr to newly allocated buffer containing decompressed data + OutBytes = number of bytes in OutBuf } +procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; + out OutBuf: Pointer; out OutBytes: Integer); + + +{ DecompressBuf decompresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + OutEstimate = zero, or est. size of the decompressed data + Out: OutBuf = ptr to newly allocated buffer containing decompressed data + OutBytes = number of bytes in OutBuf } +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); + +{ DecompressToUserBuf decompresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + Out: OutBuf = ptr to user-allocated buffer to contain decompressed data + BufSize = number of bytes in OutBuf } +procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; + const OutBuf: Pointer; BufSize: Integer); + +const + zlib_version = '1.2.8'; + +type + EZlibError = class(Exception); + ECompressionError = class(EZlibError); + EDecompressionError = class(EZlibError); + +implementation + +uses ZLibConst; + +const + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = (-1); + Z_STREAM_ERROR = (-2); + Z_DATA_ERROR = (-3); + Z_MEM_ERROR = (-4); + Z_BUF_ERROR = (-5); + Z_VERSION_ERROR = (-6); + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = (-1); + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_RLE = 3; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_ASCII = 1; + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + + +{$L adler32.obj} +{$L compress.obj} +{$L crc32.obj} +{$L deflate.obj} +{$L infback.obj} +{$L inffast.obj} +{$L inflate.obj} +{$L inftrees.obj} +{$L trees.obj} +{$L uncompr.obj} +{$L zutil.obj} + +procedure adler32; external; +procedure compressBound; external; +procedure crc32; external; +procedure deflateInit2_; external; +procedure deflateParams; external; + +function _malloc(Size: Integer): Pointer; cdecl; +begin + Result := AllocMem(Size); +end; + +procedure _free(Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; +begin + FillChar(P^, count, B); +end; + +procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; +begin + Move(source^, dest^, count); +end; + + + +// deflate compresses data +function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar; + recsize: Integer): Integer; external; +function deflate(var strm: TZStreamRec; flush: Integer): Integer; external; +function deflateEnd(var strm: TZStreamRec): Integer; external; + +// inflate decompresses data +function inflateInit_(var strm: TZStreamRec; version: PChar; + recsize: Integer): Integer; external; +function inflate(var strm: TZStreamRec; flush: Integer): Integer; external; +function inflateEnd(var strm: TZStreamRec): Integer; external; +function inflateReset(var strm: TZStreamRec): Integer; external; + + +function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl; +begin +// GetMem(Result, Items*Size); + Result := AllocMem(Items * Size); +end; + +procedure zlibFreeMem(AppData, Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +{function zlibCheck(code: Integer): Integer; +begin + Result := code; + if code < 0 then + raise EZlibError.Create('error'); //!! +end;} + +function CCheck(code: Integer): Integer; +begin + Result := code; + if code < 0 then + raise ECompressionError.Create('error'); //!! +end; + +function DCheck(code: Integer): Integer; +begin + Result := code; + if code < 0 then + raise EDecompressionError.Create('error'); //!! +end; + +procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; + out OutBuf: Pointer; out OutBytes: Integer); +var + strm: TZStreamRec; + P: Pointer; +begin + FillChar(strm, sizeof(strm), 0); + strm.zalloc := zlibAllocMem; + strm.zfree := zlibFreeMem; + OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm))); + try + while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, 256); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := 256; + end; + finally + CCheck(deflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + + +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); +var + strm: TZStreamRec; + P: Pointer; + BufInc: Integer; +begin + FillChar(strm, sizeof(strm), 0); + strm.zalloc := zlibAllocMem; + strm.zfree := zlibFreeMem; + BufInc := (InBytes + 255) and not 255; + if OutEstimate = 0 then + OutBytes := BufInc + else + OutBytes := OutEstimate; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); + try + while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, BufInc); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P))); + strm.avail_out := BufInc; + end; + finally + DCheck(inflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise + end; +end; + +procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; + const OutBuf: Pointer; BufSize: Integer); +var + strm: TZStreamRec; +begin + FillChar(strm, sizeof(strm), 0); + strm.zalloc := zlibAllocMem; + strm.zfree := zlibFreeMem; + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := BufSize; + DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); + try + if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then + raise EZlibError.CreateRes(@sTargetBufferTooSmall); + finally + DCheck(inflateEnd(strm)); + end; +end; + +// TCustomZlibStream + +constructor TCustomZLibStream.Create(Strm: TStream); +begin + inherited Create; + FStrm := Strm; + FStrmPos := Strm.Position; + FZRec.zalloc := zlibAllocMem; + FZRec.zfree := zlibFreeMem; +end; + +procedure TCustomZLibStream.Progress(Sender: TObject); +begin + if Assigned(FOnProgress) then FOnProgress(Sender); +end; + + +// TCompressionStream + +constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel; + Dest: TStream); +const + Levels: array [TCompressionLevel] of ShortInt = + (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION); +begin + inherited Create(Dest); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec))); +end; + +destructor TCompressionStream.Destroy; +begin + FZRec.next_in := nil; + FZRec.avail_in := 0; + try + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END) + and (FZRec.avail_out = 0) do + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + end; + if FZRec.avail_out < sizeof(FBuffer) then + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out); + finally + deflateEnd(FZRec); + end; + inherited Destroy; +end; + +function TCompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + raise ECompressionError.CreateRes(@sInvalidStreamOp); +end; + +function TCompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + FZRec.next_in := @Buffer; + FZRec.avail_in := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_in > 0) do + begin + CCheck(deflate(FZRec, 0)); + if FZRec.avail_out = 0 then + begin + FStrm.WriteBuffer(FBuffer, sizeof(FBuffer)); + FZRec.next_out := FBuffer; + FZRec.avail_out := sizeof(FBuffer); + FStrmPos := FStrm.Position; + Progress(Self); + end; + end; + Result := Count; +end; + +function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +begin + if (Offset = 0) and (Origin = soFromCurrent) then + Result := FZRec.total_in + else + raise ECompressionError.CreateRes(@sInvalidStreamOp); +end; + +function TCompressionStream.GetCompressionRate: Single; +begin + if FZRec.total_in = 0 then + Result := 0 + else + Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0; +end; + + +// TDecompressionStream + +constructor TDecompressionStream.Create(Source: TStream); +begin + inherited Create(Source); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec))); +end; + +destructor TDecompressionStream.Destroy; +begin + FStrm.Seek(-FZRec.avail_in, 1); + inflateEnd(FZRec); + inherited Destroy; +end; + +function TDecompressionStream.Read(var Buffer; Count: Longint): Longint; +begin + FZRec.next_out := @Buffer; + FZRec.avail_out := Count; + if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos; + while (FZRec.avail_out > 0) do + begin + if FZRec.avail_in = 0 then + begin + FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer)); + if FZRec.avail_in = 0 then + begin + Result := Count - FZRec.avail_out; + Exit; + end; + FZRec.next_in := FBuffer; + FStrmPos := FStrm.Position; + Progress(Self); + end; + CCheck(inflate(FZRec, 0)); + end; + Result := Count; +end; + +function TDecompressionStream.Write(const Buffer; Count: Longint): Longint; +begin + raise EDecompressionError.CreateRes(@sInvalidStreamOp); +end; + +function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint; +var + I: Integer; + Buf: array [0..4095] of Char; +begin + if (Offset = 0) and (Origin = soFromBeginning) then + begin + DCheck(inflateReset(FZRec)); + FZRec.next_in := FBuffer; + FZRec.avail_in := 0; + FStrm.Position := 0; + FStrmPos := 0; + end + else if ( (Offset >= 0) and (Origin = soFromCurrent)) or + ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then + begin + if Origin = soFromBeginning then Dec(Offset, FZRec.total_out); + if Offset > 0 then + begin + for I := 1 to Offset div sizeof(Buf) do + ReadBuffer(Buf, sizeof(Buf)); + ReadBuffer(Buf, Offset mod sizeof(Buf)); + end; + end + else + raise EDecompressionError.CreateRes(@sInvalidStreamOp); + Result := FZRec.total_out; +end; + + +end. diff --git a/libz/contrib/delphi/ZLibConst.pas b/libz/contrib/delphi/ZLibConst.pas new file mode 100644 index 000000000..cdfe13671 --- /dev/null +++ b/libz/contrib/delphi/ZLibConst.pas @@ -0,0 +1,11 @@ +unit ZLibConst; + +interface + +resourcestring + sTargetBufferTooSmall = 'ZLib error: target buffer may be too small'; + sInvalidStreamOp = 'Invalid stream operation'; + +implementation + +end. diff --git a/libz/contrib/delphi/readme.txt b/libz/contrib/delphi/readme.txt new file mode 100644 index 000000000..2dc9a8bba --- /dev/null +++ b/libz/contrib/delphi/readme.txt @@ -0,0 +1,76 @@ + +Overview +======== + +This directory contains an update to the ZLib interface unit, +distributed by Borland as a Delphi supplemental component. + +The original ZLib unit is Copyright (c) 1997,99 Borland Corp., +and is based on zlib version 1.0.4. There are a series of bugs +and security problems associated with that old zlib version, and +we recommend the users to update their ZLib unit. + + +Summary of modifications +======================== + +- Improved makefile, adapted to zlib version 1.2.1. + +- Some field types from TZStreamRec are changed from Integer to + Longint, for consistency with the zlib.h header, and for 64-bit + readiness. + +- The zlib_version constant is updated. + +- The new Z_RLE strategy has its corresponding symbolic constant. + +- The allocation and deallocation functions and function types + (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl, + and _malloc and _free are added as C RTL stubs. As a result, + the original C sources of zlib can be compiled out of the box, + and linked to the ZLib unit. + + +Suggestions for improvements +============================ + +Currently, the ZLib unit provides only a limited wrapper around +the zlib library, and much of the original zlib functionality is +missing. Handling compressed file formats like ZIP/GZIP or PNG +cannot be implemented without having this functionality. +Applications that handle these formats are either using their own, +duplicated code, or not using the ZLib unit at all. + +Here are a few suggestions: + +- Checksum class wrappers around adler32() and crc32(), similar + to the Java classes that implement the java.util.zip.Checksum + interface. + +- The ability to read and write raw deflate streams, without the + zlib stream header and trailer. Raw deflate streams are used + in the ZIP file format. + +- The ability to read and write gzip streams, used in the GZIP + file format, and normally produced by the gzip program. + +- The ability to select a different compression strategy, useful + to PNG and MNG image compression, and to multimedia compression + in general. Besides the compression level + + TCompressionLevel = (clNone, clFastest, clDefault, clMax); + + which, in fact, could have used the 'z' prefix and avoided + TColor-like symbols + + TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax); + + there could be a compression strategy + + TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle); + +- ZIP and GZIP stream handling via TStreams. + + +-- +Cosmin Truta diff --git a/libz/contrib/delphi/zlibd32.mak b/libz/contrib/delphi/zlibd32.mak new file mode 100644 index 000000000..9bb00b7cc --- /dev/null +++ b/libz/contrib/delphi/zlibd32.mak @@ -0,0 +1,99 @@ +# Makefile for zlib +# For use with Delphi and C++ Builder under Win32 +# Updated for zlib 1.2.x by Cosmin Truta + +# ------------ Borland C++ ------------ + +# This project uses the Delphi (fastcall/register) calling convention: +LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl + +CC = bcc32 +LD = bcc32 +AR = tlib +# do not use "-pr" in CFLAGS +CFLAGS = -a -d -k- -O2 $(LOC) +LDFLAGS = + + +# variables +ZLIB_LIB = zlib.lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# For the sake of the old Borland make, +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + + +# cleanup +clean: + -del *.obj + -del *.exe + -del *.lib + -del *.tds + -del zlib.bak + -del foo.gz + diff --git a/libz/contrib/dotzlib/DotZLib.build b/libz/contrib/dotzlib/DotZLib.build new file mode 100644 index 000000000..7f90d6bc7 --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib.build @@ -0,0 +1,33 @@ + + + A .Net wrapper library around ZLib1.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libz/contrib/dotzlib/DotZLib.sln b/libz/contrib/dotzlib/DotZLib.sln new file mode 100644 index 000000000..ac45ca048 --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/libz/contrib/dotzlib/DotZLib/AssemblyInfo.cs b/libz/contrib/dotzlib/DotZLib/AssemblyInfo.cs new file mode 100644 index 000000000..0491bfc2b --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("DotZLib")] +[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Henrik Ravn")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/libz/contrib/dotzlib/DotZLib/ChecksumImpl.cs b/libz/contrib/dotzlib/DotZLib/ChecksumImpl.cs new file mode 100644 index 000000000..788b2fcec --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/ChecksumImpl.cs @@ -0,0 +1,202 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Runtime.InteropServices; +using System.Text; + + +namespace DotZLib +{ + #region ChecksumGeneratorBase + /// + /// Implements the common functionality needed for all s + /// + /// + public abstract class ChecksumGeneratorBase : ChecksumGenerator + { + /// + /// The value of the current checksum + /// + protected uint _current; + + /// + /// Initializes a new instance of the checksum generator base - the current checksum is + /// set to zero + /// + public ChecksumGeneratorBase() + { + _current = 0; + } + + /// + /// Initializes a new instance of the checksum generator basewith a specified value + /// + /// The value to set the current checksum to + public ChecksumGeneratorBase(uint initialValue) + { + _current = initialValue; + } + + /// + /// Resets the current checksum to zero + /// + public void Reset() { _current = 0; } + + /// + /// Gets the current checksum value + /// + public uint Value { get { return _current; } } + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + /// All the other Update methods are implmeneted in terms of this one. + /// This is therefore the only method a derived class has to implement + public abstract void Update(byte[] data, int offset, int count); + + /// + /// Updates the current checksum with an array of bytes. + /// + /// The data to update the checksum with + public void Update(byte[] data) + { + Update(data, 0, data.Length); + } + + /// + /// Updates the current checksum with the data from a string + /// + /// The string to update the checksum with + /// The characters in the string are converted by the UTF-8 encoding + public void Update(string data) + { + Update(Encoding.UTF8.GetBytes(data)); + } + + /// + /// Updates the current checksum with the data from a string, using a specific encoding + /// + /// The string to update the checksum with + /// The encoding to use + public void Update(string data, Encoding encoding) + { + Update(encoding.GetBytes(data)); + } + + } + #endregion + + #region CRC32 + /// + /// Implements a CRC32 checksum generator + /// + public sealed class CRC32Checksum : ChecksumGeneratorBase + { + #region DLL imports + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint crc32(uint crc, int data, uint length); + + #endregion + + /// + /// Initializes a new instance of the CRC32 checksum generator + /// + public CRC32Checksum() : base() {} + + /// + /// Initializes a new instance of the CRC32 checksum generator with a specified value + /// + /// The value to set the current checksum to + public CRC32Checksum(uint initialValue) : base(initialValue) {} + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + public override void Update(byte[] data, int offset, int count) + { + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); + } + finally + { + hData.Free(); + } + } + + } + #endregion + + #region Adler + /// + /// Implements a checksum generator that computes the Adler checksum on data + /// + public sealed class AdlerChecksum : ChecksumGeneratorBase + { + #region DLL imports + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint adler32(uint adler, int data, uint length); + + #endregion + + /// + /// Initializes a new instance of the Adler checksum generator + /// + public AdlerChecksum() : base() {} + + /// + /// Initializes a new instance of the Adler checksum generator with a specified value + /// + /// The value to set the current checksum to + public AdlerChecksum(uint initialValue) : base(initialValue) {} + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + public override void Update(byte[] data, int offset, int count) + { + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); + } + finally + { + hData.Free(); + } + } + + } + #endregion + +} \ No newline at end of file diff --git a/libz/contrib/dotzlib/DotZLib/CircularBuffer.cs b/libz/contrib/dotzlib/DotZLib/CircularBuffer.cs new file mode 100644 index 000000000..c1cab3a02 --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/CircularBuffer.cs @@ -0,0 +1,83 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; + +namespace DotZLib +{ + + /// + /// This class implements a circular buffer + /// + internal class CircularBuffer + { + #region Private data + private int _capacity; + private int _head; + private int _tail; + private int _size; + private byte[] _buffer; + #endregion + + public CircularBuffer(int capacity) + { + Debug.Assert( capacity > 0 ); + _buffer = new byte[capacity]; + _capacity = capacity; + _head = 0; + _tail = 0; + _size = 0; + } + + public int Size { get { return _size; } } + + public int Put(byte[] source, int offset, int count) + { + Debug.Assert( count > 0 ); + int trueCount = Math.Min(count, _capacity - Size); + for (int i = 0; i < trueCount; ++i) + _buffer[(_tail+i) % _capacity] = source[offset+i]; + _tail += trueCount; + _tail %= _capacity; + _size += trueCount; + return trueCount; + } + + public bool Put(byte b) + { + if (Size == _capacity) // no room + return false; + _buffer[_tail++] = b; + _tail %= _capacity; + ++_size; + return true; + } + + public int Get(byte[] destination, int offset, int count) + { + int trueCount = Math.Min(count,Size); + for (int i = 0; i < trueCount; ++i) + destination[offset + i] = _buffer[(_head+i) % _capacity]; + _head += trueCount; + _head %= _capacity; + _size -= trueCount; + return trueCount; + } + + public int Get() + { + if (Size == 0) + return -1; + + int result = (int)_buffer[_head++ % _capacity]; + --_size; + return result; + } + + } +} diff --git a/libz/contrib/dotzlib/DotZLib/CodecBase.cs b/libz/contrib/dotzlib/DotZLib/CodecBase.cs new file mode 100644 index 000000000..42e6da3a5 --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/CodecBase.cs @@ -0,0 +1,198 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + /// + /// Implements the common functionality needed for all s + /// + public abstract class CodecBase : Codec, IDisposable + { + + #region Data members + + /// + /// Instance of the internal zlib buffer structure that is + /// passed to all functions in the zlib dll + /// + internal ZStream _ztream = new ZStream(); + + /// + /// True if the object instance has been disposed, false otherwise + /// + protected bool _isDisposed = false; + + /// + /// The size of the internal buffers + /// + protected const int kBufferSize = 16384; + + private byte[] _outBuffer = new byte[kBufferSize]; + private byte[] _inBuffer = new byte[kBufferSize]; + + private GCHandle _hInput; + private GCHandle _hOutput; + + private uint _checksum = 0; + + #endregion + + /// + /// Initializes a new instance of the CodeBase class. + /// + public CodecBase() + { + try + { + _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned); + _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned); + } + catch (Exception) + { + CleanUp(false); + throw; + } + } + + + #region Codec Members + + /// + /// Occurs when more processed data are available. + /// + public event DataAvailableHandler DataAvailable; + + /// + /// Fires the event + /// + protected void OnDataAvailable() + { + if (_ztream.total_out > 0) + { + if (DataAvailable != null) + DataAvailable( _outBuffer, 0, (int)_ztream.total_out); + resetOutput(); + } + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// Adding data may, or may not, raise the DataAvailable event + public void Add(byte[] data) + { + Add(data,0,data.Length); + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + /// This must be implemented by a derived class + public abstract void Add(byte[] data, int offset, int count); + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + /// This must be implemented by a derived class + public abstract void Finish(); + + /// + /// Gets the checksum of the data that has been added so far + /// + public uint Checksum { get { return _checksum; } } + + #endregion + + #region Destructor & IDisposable stuff + + /// + /// Destroys this instance + /// + ~CodecBase() + { + CleanUp(false); + } + + /// + /// Releases any unmanaged resources and calls the method of the derived class + /// + public void Dispose() + { + CleanUp(true); + } + + /// + /// Performs any codec specific cleanup + /// + /// This must be implemented by a derived class + protected abstract void CleanUp(); + + // performs the release of the handles and calls the dereived CleanUp() + private void CleanUp(bool isDisposing) + { + if (!_isDisposed) + { + CleanUp(); + if (_hInput.IsAllocated) + _hInput.Free(); + if (_hOutput.IsAllocated) + _hOutput.Free(); + + _isDisposed = true; + } + } + + + #endregion + + #region Helper methods + + /// + /// Copies a number of bytes to the internal codec buffer - ready for proccesing + /// + /// The byte array that contains the data to copy + /// The index of the first byte to copy + /// The number of bytes to copy from data + protected void copyInput(byte[] data, int startIndex, int count) + { + Array.Copy(data, startIndex, _inBuffer,0, count); + _ztream.next_in = _hInput.AddrOfPinnedObject(); + _ztream.total_in = 0; + _ztream.avail_in = (uint)count; + + } + + /// + /// Resets the internal output buffers to a known state - ready for processing + /// + protected void resetOutput() + { + _ztream.total_out = 0; + _ztream.avail_out = kBufferSize; + _ztream.next_out = _hOutput.AddrOfPinnedObject(); + } + + /// + /// Updates the running checksum property + /// + /// The new checksum value + protected void setChecksum(uint newSum) + { + _checksum = newSum; + } + #endregion + + } +} diff --git a/libz/contrib/dotzlib/DotZLib/Deflater.cs b/libz/contrib/dotzlib/DotZLib/Deflater.cs new file mode 100644 index 000000000..c2477925b --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/Deflater.cs @@ -0,0 +1,106 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + + /// + /// Implements a data compressor, using the deflate algorithm in the ZLib dll + /// + public sealed class Deflater : CodecBase + { + #region Dll imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflate(ref ZStream sz, int flush); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflateReset(ref ZStream sz); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflateEnd(ref ZStream sz); + #endregion + + /// + /// Constructs an new instance of the Deflater + /// + /// The compression level to use for this Deflater + public Deflater(CompressLevel level) : base() + { + int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream)); + if (retval != 0) + throw new ZLibException(retval, "Could not initialize deflater"); + + resetOutput(); + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + public override void Add(byte[] data, int offset, int count) + { + if (data == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + + int total = count; + int inputIndex = offset; + int err = 0; + + while (err >= 0 && inputIndex < total) + { + copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); + while (err >= 0 && _ztream.avail_in > 0) + { + err = deflate(ref _ztream, (int)FlushTypes.None); + if (err == 0) + while (_ztream.avail_out == 0) + { + OnDataAvailable(); + err = deflate(ref _ztream, (int)FlushTypes.None); + } + inputIndex += (int)_ztream.total_in; + } + } + setChecksum( _ztream.adler ); + } + + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + public override void Finish() + { + int err; + do + { + err = deflate(ref _ztream, (int)FlushTypes.Finish); + OnDataAvailable(); + } + while (err == 0); + setChecksum( _ztream.adler ); + deflateReset(ref _ztream); + resetOutput(); + } + + /// + /// Closes the internal zlib deflate stream + /// + protected override void CleanUp() { deflateEnd(ref _ztream); } + + } +} diff --git a/libz/contrib/dotzlib/DotZLib/DotZLib.cs b/libz/contrib/dotzlib/DotZLib/DotZLib.cs new file mode 100644 index 000000000..be184b4c7 --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/DotZLib.cs @@ -0,0 +1,288 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; + + +namespace DotZLib +{ + + #region Internal types + + /// + /// Defines constants for the various flush types used with zlib + /// + internal enum FlushTypes + { + None, Partial, Sync, Full, Finish, Block + } + + #region ZStream structure + // internal mapping of the zlib zstream structure for marshalling + [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)] + internal struct ZStream + { + public IntPtr next_in; + public uint avail_in; + public uint total_in; + + public IntPtr next_out; + public uint avail_out; + public uint total_out; + + [MarshalAs(UnmanagedType.LPStr)] + string msg; + uint state; + + uint zalloc; + uint zfree; + uint opaque; + + int data_type; + public uint adler; + uint reserved; + } + + #endregion + + #endregion + + #region Public enums + /// + /// Defines constants for the available compression levels in zlib + /// + public enum CompressLevel : int + { + /// + /// The default compression level with a reasonable compromise between compression and speed + /// + Default = -1, + /// + /// No compression at all. The data are passed straight through. + /// + None = 0, + /// + /// The maximum compression rate available. + /// + Best = 9, + /// + /// The fastest available compression level. + /// + Fastest = 1 + } + #endregion + + #region Exception classes + /// + /// The exception that is thrown when an error occurs on the zlib dll + /// + public class ZLibException : ApplicationException + { + /// + /// Initializes a new instance of the class with a specified + /// error message and error code + /// + /// The zlib error code that caused the exception + /// A message that (hopefully) describes the error + public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg)) + { + } + + /// + /// Initializes a new instance of the class with a specified + /// error code + /// + /// The zlib error code that caused the exception + public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode)) + { + } + } + #endregion + + #region Interfaces + + /// + /// Declares methods and properties that enables a running checksum to be calculated + /// + public interface ChecksumGenerator + { + /// + /// Gets the current value of the checksum + /// + uint Value { get; } + + /// + /// Clears the current checksum to 0 + /// + void Reset(); + + /// + /// Updates the current checksum with an array of bytes + /// + /// The data to update the checksum with + void Update(byte[] data); + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + void Update(byte[] data, int offset, int count); + + /// + /// Updates the current checksum with the data from a string + /// + /// The string to update the checksum with + /// The characters in the string are converted by the UTF-8 encoding + void Update(string data); + + /// + /// Updates the current checksum with the data from a string, using a specific encoding + /// + /// The string to update the checksum with + /// The encoding to use + void Update(string data, Encoding encoding); + } + + + /// + /// Represents the method that will be called from a codec when new data + /// are available. + /// + /// The byte array containing the processed data + /// The index of the first processed byte in data + /// The number of processed bytes available + /// On return from this method, the data may be overwritten, so grab it while you can. + /// You cannot assume that startIndex will be zero. + /// + public delegate void DataAvailableHandler(byte[] data, int startIndex, int count); + + /// + /// Declares methods and events for implementing compressors/decompressors + /// + public interface Codec + { + /// + /// Occurs when more processed data are available. + /// + event DataAvailableHandler DataAvailable; + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// Adding data may, or may not, raise the DataAvailable event + void Add(byte[] data); + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + void Add(byte[] data, int offset, int count); + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + void Finish(); + + /// + /// Gets the checksum of the data that has been added so far + /// + uint Checksum { get; } + + + } + + #endregion + + #region Classes + /// + /// Encapsulates general information about the ZLib library + /// + public class Info + { + #region DLL imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint zlibCompileFlags(); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern string zlibVersion(); + #endregion + + #region Private stuff + private uint _flags; + + // helper function that unpacks a bitsize mask + private static int bitSize(uint bits) + { + switch (bits) + { + case 0: return 16; + case 1: return 32; + case 2: return 64; + } + return -1; + } + #endregion + + /// + /// Constructs an instance of the Info class. + /// + public Info() + { + _flags = zlibCompileFlags(); + } + + /// + /// True if the library is compiled with debug info + /// + public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } } + + /// + /// True if the library is compiled with assembly optimizations + /// + public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } } + + /// + /// Gets the size of the unsigned int that was compiled into Zlib + /// + public int SizeOfUInt { get { return bitSize(_flags & 3); } } + + /// + /// Gets the size of the unsigned long that was compiled into Zlib + /// + public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } } + + /// + /// Gets the size of the pointers that were compiled into Zlib + /// + public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } } + + /// + /// Gets the size of the z_off_t type that was compiled into Zlib + /// + public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } } + + /// + /// Gets the version of ZLib as a string, e.g. "1.2.1" + /// + public static string Version { get { return zlibVersion(); } } + } + + #endregion + +} diff --git a/libz/contrib/dotzlib/DotZLib/DotZLib.csproj b/libz/contrib/dotzlib/DotZLib/DotZLib.csproj new file mode 100644 index 000000000..71eeb8590 --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/DotZLib.csproj @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libz/contrib/dotzlib/DotZLib/GZipStream.cs b/libz/contrib/dotzlib/DotZLib/GZipStream.cs new file mode 100644 index 000000000..b161300b1 --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/GZipStream.cs @@ -0,0 +1,301 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + /// + /// Implements a compressed , in GZip (.gz) format. + /// + public class GZipStream : Stream, IDisposable + { + #region Dll Imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern IntPtr gzopen(string name, string mode); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzclose(IntPtr gzFile); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzwrite(IntPtr gzFile, int data, int length); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzread(IntPtr gzFile, int data, int length); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzgetc(IntPtr gzFile); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzputc(IntPtr gzFile, int c); + + #endregion + + #region Private data + private IntPtr _gzFile; + private bool _isDisposed = false; + private bool _isWriting; + #endregion + + #region Constructors + /// + /// Creates a new file as a writeable GZipStream + /// + /// The name of the compressed file to create + /// The compression level to use when adding data + /// If an error occurred in the internal zlib function + public GZipStream(string fileName, CompressLevel level) + { + _isWriting = true; + _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level)); + if (_gzFile == IntPtr.Zero) + throw new ZLibException(-1, "Could not open " + fileName); + } + + /// + /// Opens an existing file as a readable GZipStream + /// + /// The name of the file to open + /// If an error occurred in the internal zlib function + public GZipStream(string fileName) + { + _isWriting = false; + _gzFile = gzopen(fileName, "rb"); + if (_gzFile == IntPtr.Zero) + throw new ZLibException(-1, "Could not open " + fileName); + + } + #endregion + + #region Access properties + /// + /// Returns true of this stream can be read from, false otherwise + /// + public override bool CanRead + { + get + { + return !_isWriting; + } + } + + + /// + /// Returns false. + /// + public override bool CanSeek + { + get + { + return false; + } + } + + /// + /// Returns true if this tsream is writeable, false otherwise + /// + public override bool CanWrite + { + get + { + return _isWriting; + } + } + #endregion + + #region Destructor & IDispose stuff + + /// + /// Destroys this instance + /// + ~GZipStream() + { + cleanUp(false); + } + + /// + /// Closes the external file handle + /// + public void Dispose() + { + cleanUp(true); + } + + // Does the actual closing of the file handle. + private void cleanUp(bool isDisposing) + { + if (!_isDisposed) + { + gzclose(_gzFile); + _isDisposed = true; + } + } + #endregion + + #region Basic reading and writing + /// + /// Attempts to read a number of bytes from the stream. + /// + /// The destination data buffer + /// The index of the first destination byte in buffer + /// The number of bytes requested + /// The number of bytes read + /// If buffer is null + /// If count or offset are negative + /// If offset + count is > buffer.Length + /// If this stream is not readable. + /// If this stream has been disposed. + public override int Read(byte[] buffer, int offset, int count) + { + if (!CanRead) throw new NotSupportedException(); + if (buffer == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > buffer.Length) throw new ArgumentException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); + int result; + try + { + result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); + if (result < 0) + throw new IOException(); + } + finally + { + h.Free(); + } + return result; + } + + /// + /// Attempts to read a single byte from the stream. + /// + /// The byte that was read, or -1 in case of error or End-Of-File + public override int ReadByte() + { + if (!CanRead) throw new NotSupportedException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + return gzgetc(_gzFile); + } + + /// + /// Writes a number of bytes to the stream + /// + /// + /// + /// + /// If buffer is null + /// If count or offset are negative + /// If offset + count is > buffer.Length + /// If this stream is not writeable. + /// If this stream has been disposed. + public override void Write(byte[] buffer, int offset, int count) + { + if (!CanWrite) throw new NotSupportedException(); + if (buffer == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > buffer.Length) throw new ArgumentException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); + try + { + int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); + if (result < 0) + throw new IOException(); + } + finally + { + h.Free(); + } + } + + /// + /// Writes a single byte to the stream + /// + /// The byte to add to the stream. + /// If this stream is not writeable. + /// If this stream has been disposed. + public override void WriteByte(byte value) + { + if (!CanWrite) throw new NotSupportedException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + int result = gzputc(_gzFile, (int)value); + if (result < 0) + throw new IOException(); + } + #endregion + + #region Position & length stuff + /// + /// Not supported. + /// + /// + /// Always thrown + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + /// + /// Not suppported. + /// + /// + /// + /// + /// Always thrown + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + /// + /// Flushes the GZipStream. + /// + /// In this implementation, this method does nothing. This is because excessive + /// flushing may degrade the achievable compression rates. + public override void Flush() + { + // left empty on purpose + } + + /// + /// Gets/sets the current position in the GZipStream. Not suppported. + /// + /// In this implementation this property is not supported + /// Always thrown + public override long Position + { + get + { + throw new NotSupportedException(); + } + set + { + throw new NotSupportedException(); + } + } + + /// + /// Gets the size of the stream. Not suppported. + /// + /// In this implementation this property is not supported + /// Always thrown + public override long Length + { + get + { + throw new NotSupportedException(); + } + } + #endregion + } +} diff --git a/libz/contrib/dotzlib/DotZLib/Inflater.cs b/libz/contrib/dotzlib/DotZLib/Inflater.cs new file mode 100644 index 000000000..8ed5451d6 --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/Inflater.cs @@ -0,0 +1,105 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + + /// + /// Implements a data decompressor, using the inflate algorithm in the ZLib dll + /// + public class Inflater : CodecBase + { + #region Dll imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern int inflateInit_(ref ZStream sz, string vs, int size); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflate(ref ZStream sz, int flush); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflateReset(ref ZStream sz); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflateEnd(ref ZStream sz); + #endregion + + /// + /// Constructs an new instance of the Inflater + /// + public Inflater() : base() + { + int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream)); + if (retval != 0) + throw new ZLibException(retval, "Could not initialize inflater"); + + resetOutput(); + } + + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + public override void Add(byte[] data, int offset, int count) + { + if (data == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + + int total = count; + int inputIndex = offset; + int err = 0; + + while (err >= 0 && inputIndex < total) + { + copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); + err = inflate(ref _ztream, (int)FlushTypes.None); + if (err == 0) + while (_ztream.avail_out == 0) + { + OnDataAvailable(); + err = inflate(ref _ztream, (int)FlushTypes.None); + } + + inputIndex += (int)_ztream.total_in; + } + setChecksum( _ztream.adler ); + } + + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + public override void Finish() + { + int err; + do + { + err = inflate(ref _ztream, (int)FlushTypes.Finish); + OnDataAvailable(); + } + while (err == 0); + setChecksum( _ztream.adler ); + inflateReset(ref _ztream); + resetOutput(); + } + + /// + /// Closes the internal zlib inflate stream + /// + protected override void CleanUp() { inflateEnd(ref _ztream); } + + + } +} diff --git a/libz/contrib/dotzlib/DotZLib/UnitTests.cs b/libz/contrib/dotzlib/DotZLib/UnitTests.cs new file mode 100644 index 000000000..b273d54b3 --- /dev/null +++ b/libz/contrib/dotzlib/DotZLib/UnitTests.cs @@ -0,0 +1,274 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Collections; +using System.IO; + +// uncomment the define below to include unit tests +//#define nunit +#if nunit +using NUnit.Framework; + +// Unit tests for the DotZLib class library +// ---------------------------------------- +// +// Use this with NUnit 2 from http://www.nunit.org +// + +namespace DotZLibTests +{ + using DotZLib; + + // helper methods + internal class Utils + { + public static bool byteArrEqual( byte[] lhs, byte[] rhs ) + { + if (lhs.Length != rhs.Length) + return false; + for (int i = lhs.Length-1; i >= 0; --i) + if (lhs[i] != rhs[i]) + return false; + return true; + } + + } + + + [TestFixture] + public class CircBufferTests + { + #region Circular buffer tests + [Test] + public void SinglePutGet() + { + CircularBuffer buf = new CircularBuffer(10); + Assert.AreEqual( 0, buf.Size ); + Assert.AreEqual( -1, buf.Get() ); + + Assert.IsTrue(buf.Put( 1 )); + Assert.AreEqual( 1, buf.Size ); + Assert.AreEqual( 1, buf.Get() ); + Assert.AreEqual( 0, buf.Size ); + Assert.AreEqual( -1, buf.Get() ); + } + + [Test] + public void BlockPutGet() + { + CircularBuffer buf = new CircularBuffer(10); + byte[] arr = {1,2,3,4,5,6,7,8,9,10}; + Assert.AreEqual( 10, buf.Put(arr,0,10) ); + Assert.AreEqual( 10, buf.Size ); + Assert.IsFalse( buf.Put(11) ); + Assert.AreEqual( 1, buf.Get() ); + Assert.IsTrue( buf.Put(11) ); + + byte[] arr2 = (byte[])arr.Clone(); + Assert.AreEqual( 9, buf.Get(arr2,1,9) ); + Assert.IsTrue( Utils.byteArrEqual(arr,arr2) ); + } + + #endregion + } + + [TestFixture] + public class ChecksumTests + { + #region CRC32 Tests + [Test] + public void CRC32_Null() + { + CRC32Checksum crc32 = new CRC32Checksum(); + Assert.AreEqual( 0, crc32.Value ); + + crc32 = new CRC32Checksum(1); + Assert.AreEqual( 1, crc32.Value ); + + crc32 = new CRC32Checksum(556); + Assert.AreEqual( 556, crc32.Value ); + } + + [Test] + public void CRC32_Data() + { + CRC32Checksum crc32 = new CRC32Checksum(); + byte[] data = { 1,2,3,4,5,6,7 }; + crc32.Update(data); + Assert.AreEqual( 0x70e46888, crc32.Value ); + + crc32 = new CRC32Checksum(); + crc32.Update("penguin"); + Assert.AreEqual( 0x0e5c1a120, crc32.Value ); + + crc32 = new CRC32Checksum(1); + crc32.Update("penguin"); + Assert.AreEqual(0x43b6aa94, crc32.Value); + + } + #endregion + + #region Adler tests + + [Test] + public void Adler_Null() + { + AdlerChecksum adler = new AdlerChecksum(); + Assert.AreEqual(0, adler.Value); + + adler = new AdlerChecksum(1); + Assert.AreEqual( 1, adler.Value ); + + adler = new AdlerChecksum(556); + Assert.AreEqual( 556, adler.Value ); + } + + [Test] + public void Adler_Data() + { + AdlerChecksum adler = new AdlerChecksum(1); + byte[] data = { 1,2,3,4,5,6,7 }; + adler.Update(data); + Assert.AreEqual( 0x5b001d, adler.Value ); + + adler = new AdlerChecksum(); + adler.Update("penguin"); + Assert.AreEqual(0x0bcf02f6, adler.Value ); + + adler = new AdlerChecksum(1); + adler.Update("penguin"); + Assert.AreEqual(0x0bd602f7, adler.Value); + + } + #endregion + } + + [TestFixture] + public class InfoTests + { + #region Info tests + [Test] + public void Info_Version() + { + Info info = new Info(); + Assert.AreEqual("1.2.8", Info.Version); + Assert.AreEqual(32, info.SizeOfUInt); + Assert.AreEqual(32, info.SizeOfULong); + Assert.AreEqual(32, info.SizeOfPointer); + Assert.AreEqual(32, info.SizeOfOffset); + } + #endregion + } + + [TestFixture] + public class DeflateInflateTests + { + #region Deflate tests + [Test] + public void Deflate_Init() + { + using (Deflater def = new Deflater(CompressLevel.Default)) + { + } + } + + private ArrayList compressedData = new ArrayList(); + private uint adler1; + + private ArrayList uncompressedData = new ArrayList(); + private uint adler2; + + public void CDataAvail(byte[] data, int startIndex, int count) + { + for (int i = 0; i < count; ++i) + compressedData.Add(data[i+startIndex]); + } + + [Test] + public void Deflate_Compress() + { + compressedData.Clear(); + + byte[] testData = new byte[35000]; + for (int i = 0; i < testData.Length; ++i) + testData[i] = 5; + + using (Deflater def = new Deflater((CompressLevel)5)) + { + def.DataAvailable += new DataAvailableHandler(CDataAvail); + def.Add(testData); + def.Finish(); + adler1 = def.Checksum; + } + } + #endregion + + #region Inflate tests + [Test] + public void Inflate_Init() + { + using (Inflater inf = new Inflater()) + { + } + } + + private void DDataAvail(byte[] data, int startIndex, int count) + { + for (int i = 0; i < count; ++i) + uncompressedData.Add(data[i+startIndex]); + } + + [Test] + public void Inflate_Expand() + { + uncompressedData.Clear(); + + using (Inflater inf = new Inflater()) + { + inf.DataAvailable += new DataAvailableHandler(DDataAvail); + inf.Add((byte[])compressedData.ToArray(typeof(byte))); + inf.Finish(); + adler2 = inf.Checksum; + } + Assert.AreEqual( adler1, adler2 ); + } + #endregion + } + + [TestFixture] + public class GZipStreamTests + { + #region GZipStream test + [Test] + public void GZipStream_WriteRead() + { + using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best)) + { + BinaryWriter writer = new BinaryWriter(gzOut); + writer.Write("hi there"); + writer.Write(Math.PI); + writer.Write(42); + } + + using (GZipStream gzIn = new GZipStream("gzstream.gz")) + { + BinaryReader reader = new BinaryReader(gzIn); + string s = reader.ReadString(); + Assert.AreEqual("hi there",s); + double d = reader.ReadDouble(); + Assert.AreEqual(Math.PI, d); + int i = reader.ReadInt32(); + Assert.AreEqual(42,i); + } + + } + #endregion + } +} + +#endif diff --git a/libz/contrib/dotzlib/LICENSE_1_0.txt b/libz/contrib/dotzlib/LICENSE_1_0.txt new file mode 100644 index 000000000..30aac2cf4 --- /dev/null +++ b/libz/contrib/dotzlib/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/libz/contrib/dotzlib/readme.txt b/libz/contrib/dotzlib/readme.txt new file mode 100644 index 000000000..b2395720d --- /dev/null +++ b/libz/contrib/dotzlib/readme.txt @@ -0,0 +1,58 @@ +This directory contains a .Net wrapper class library for the ZLib1.dll + +The wrapper includes support for inflating/deflating memory buffers, +.Net streaming wrappers for the gz streams part of zlib, and wrappers +for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples. + +Directory structure: +-------------------- + +LICENSE_1_0.txt - License file. +readme.txt - This file. +DotZLib.chm - Class library documentation +DotZLib.build - NAnt build file +DotZLib.sln - Microsoft Visual Studio 2003 solution file + +DotZLib\*.cs - Source files for the class library + +Unit tests: +----------- +The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher. +To include unit tests in the build, define nunit before building. + + +Build instructions: +------------------- + +1. Using Visual Studio.Net 2003: + Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll) + will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on + you are building the release or debug version of the library. Check + DotZLib/UnitTests.cs for instructions on how to include unit tests in the + build. + +2. Using NAnt: + Open a command prompt with access to the build environment and run nant + in the same directory as the DotZLib.build file. + You can define 2 properties on the nant command-line to control the build: + debug={true|false} to toggle between release/debug builds (default=true). + nunit={true|false} to include or esclude unit tests (default=true). + Also the target clean will remove binaries. + Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release + or ./DotZLib/bin/debug, depending on whether you are building the release + or debug version of the library. + + Examples: + nant -D:debug=false -D:nunit=false + will build a release mode version of the library without unit tests. + nant + will build a debug version of the library with unit tests + nant clean + will remove all previously built files. + + +--------------------------------- +Copyright (c) Henrik Ravn 2004 + +Use, modification and distribution are subject to the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/libz/contrib/gcc_gvmat64/gvmat64.S b/libz/contrib/gcc_gvmat64/gvmat64.S new file mode 100644 index 000000000..dd858ddbd --- /dev/null +++ b/libz/contrib/gcc_gvmat64/gvmat64.S @@ -0,0 +1,574 @@ +/* +;uInt longest_match_x64( +; deflate_state *s, +; IPos cur_match); // current match + +; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64 +; (AMD64 on Athlon 64, Opteron, Phenom +; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7) +; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode) +; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; +; File written by Gilles Vollant, by converting to assembly the longest_match +; from Jean-loup Gailly in deflate.c of zLib and infoZip zip. +; and by taking inspiration on asm686 with masm, optimised assembly code +; from Brian Raiter, written 1998 +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software +; 3. This notice may not be removed or altered from any source distribution. +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; to compile this file for zLib, I use option: +; gcc -c -arch x86_64 gvmat64.S + + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; // current match / +; +; with XCode for Mac, I had strange error with some jump on intel syntax +; this is why BEFORE_JMP and AFTER_JMP are used + */ + + +#define BEFORE_JMP .att_syntax +#define AFTER_JMP .intel_syntax noprefix + +#ifndef NO_UNDERLINE +# define match_init _match_init +# define longest_match _longest_match +#endif + +.intel_syntax noprefix + +.globl match_init, longest_match +.text +longest_match: + + + +#define LocalVarsSize 96 +/* +; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12 +; free register : r14,r15 +; register can be saved : rsp +*/ + +#define chainlenwmask (rsp + 8 - LocalVarsSize) +#define nicematch (rsp + 16 - LocalVarsSize) + +#define save_rdi (rsp + 24 - LocalVarsSize) +#define save_rsi (rsp + 32 - LocalVarsSize) +#define save_rbx (rsp + 40 - LocalVarsSize) +#define save_rbp (rsp + 48 - LocalVarsSize) +#define save_r12 (rsp + 56 - LocalVarsSize) +#define save_r13 (rsp + 64 - LocalVarsSize) +#define save_r14 (rsp + 72 - LocalVarsSize) +#define save_r15 (rsp + 80 - LocalVarsSize) + + +/* +; all the +4 offsets are due to the addition of pending_buf_size (in zlib +; in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, remove the +4). +; Note : these value are good with a 8 bytes boundary pack structure +*/ + +#define MAX_MATCH 258 +#define MIN_MATCH 3 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) + +/* +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). +*/ + + + +/* you can check the structure offset by running + +#include +#include +#include "deflate.h" + +void print_depl() +{ +deflate_state ds; +deflate_state *s=&ds; +printf("size pointer=%u\n",(int)sizeof(void*)); + +printf("#define dsWSize %u\n",(int)(((char*)&(s->w_size))-((char*)s))); +printf("#define dsWMask %u\n",(int)(((char*)&(s->w_mask))-((char*)s))); +printf("#define dsWindow %u\n",(int)(((char*)&(s->window))-((char*)s))); +printf("#define dsPrev %u\n",(int)(((char*)&(s->prev))-((char*)s))); +printf("#define dsMatchLen %u\n",(int)(((char*)&(s->match_length))-((char*)s))); +printf("#define dsPrevMatch %u\n",(int)(((char*)&(s->prev_match))-((char*)s))); +printf("#define dsStrStart %u\n",(int)(((char*)&(s->strstart))-((char*)s))); +printf("#define dsMatchStart %u\n",(int)(((char*)&(s->match_start))-((char*)s))); +printf("#define dsLookahead %u\n",(int)(((char*)&(s->lookahead))-((char*)s))); +printf("#define dsPrevLen %u\n",(int)(((char*)&(s->prev_length))-((char*)s))); +printf("#define dsMaxChainLen %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s))); +printf("#define dsGoodMatch %u\n",(int)(((char*)&(s->good_match))-((char*)s))); +printf("#define dsNiceMatch %u\n",(int)(((char*)&(s->nice_match))-((char*)s))); +} +*/ + +#define dsWSize 68 +#define dsWMask 76 +#define dsWindow 80 +#define dsPrev 96 +#define dsMatchLen 144 +#define dsPrevMatch 148 +#define dsStrStart 156 +#define dsMatchStart 160 +#define dsLookahead 164 +#define dsPrevLen 168 +#define dsMaxChainLen 172 +#define dsGoodMatch 188 +#define dsNiceMatch 192 + +#define window_size [ rcx + dsWSize] +#define WMask [ rcx + dsWMask] +#define window_ad [ rcx + dsWindow] +#define prev_ad [ rcx + dsPrev] +#define strstart [ rcx + dsStrStart] +#define match_start [ rcx + dsMatchStart] +#define Lookahead [ rcx + dsLookahead] //; 0ffffffffh on infozip +#define prev_length [ rcx + dsPrevLen] +#define max_chain_length [ rcx + dsMaxChainLen] +#define good_match [ rcx + dsGoodMatch] +#define nice_match [ rcx + dsNiceMatch] + +/* +; windows: +; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match) + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch. + +; +; gcc on macosx-linux: +; see http://www.x86-64.org/documentation/abi-0.99.pdf +; param 1 in rdi, param 2 in rsi +; rbx, rsp, rbp, r12 to r15 must be preserved + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + +;;; Retrieve the function arguments. r8d will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + +; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match) +; mac: param 1 in rdi, param 2 rsi +; this clear high 32 bits of r8, which can be garbage in both r8 and rdx +*/ + mov [save_rbx],rbx + mov [save_rbp],rbp + + + mov rcx,rdi + + mov r8d,esi + + + mov [save_r12],r12 + mov [save_r13],r13 + mov [save_r14],r14 + mov [save_r15],r15 + + +//;;; uInt wmask = s->w_mask; +//;;; unsigned chain_length = s->max_chain_length; +//;;; if (s->prev_length >= s->good_match) { +//;;; chain_length >>= 2; +//;;; } + + + mov edi, prev_length + mov esi, good_match + mov eax, WMask + mov ebx, max_chain_length + cmp edi, esi + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +//;;; chainlen is decremented once beforehand so that the function can +//;;; use the sign flag instead of the zero flag for the exit test. +//;;; It is then shifted into the high word, to make room for the wmask +//;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + +//;;; on zlib only +//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + + + mov eax, nice_match + mov [chainlenwmask], ebx + mov r10d, Lookahead + cmp r10d, eax + cmovnl r10d, eax + mov [nicematch],r10d + + + +//;;; register Bytef *scan = s->window + s->strstart; + mov r10, window_ad + mov ebp, strstart + lea r13, [r10 + rbp] + +//;;; Determine how many bytes the scan ptr is off from being +//;;; dword-aligned. + + mov r9,r13 + neg r13 + and r13,3 + +//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +//;;; s->strstart - (IPos)MAX_DIST(s) : NIL; + + + mov eax, window_size + sub eax, MIN_LOOKAHEAD + + + xor edi,edi + sub ebp, eax + + mov r11d, prev_length + + cmovng ebp,edi + +//;;; int best_len = s->prev_length; + + +//;;; Store the sum of s->window + best_len in esi locally, and in esi. + + lea rsi,[r10+r11] + +//;;; register ush scan_start = *(ushf*)scan; +//;;; register ush scan_end = *(ushf*)(scan+best_len-1); +//;;; Posf *prev = s->prev; + + movzx r12d,word ptr [r9] + movzx ebx, word ptr [r9 + r11 - 1] + + mov rdi, prev_ad + +//;;; Jump into the main loop. + + mov edx, [chainlenwmask] + + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + + + +LookupLoop1: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + + + + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry1: + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jz LookupLoopIsZero + AFTER_JMP + +LookupLoop2: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + BEFORE_JMP + jbe LeaveNow + AFTER_JMP + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry2: + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jz LookupLoopIsZero + AFTER_JMP + +LookupLoop4: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + BEFORE_JMP + jbe LeaveNow + AFTER_JMP + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry4: + + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jnz LookupLoop1 + jmp LookupLoopIsZero + AFTER_JMP +/* +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; r8d = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit +*/ +.balign 16 +LookupLoop: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + BEFORE_JMP + jbe LeaveNow + AFTER_JMP + sub edx, 0x00010000 + BEFORE_JMP + js LeaveNow + AFTER_JMP + +LoopEntry: + + cmp bx,word ptr [rsi + r8 - 1] + BEFORE_JMP + jnz LookupLoop1 + AFTER_JMP +LookupLoopIsZero: + cmp r12w, word ptr [r10 + r8] + BEFORE_JMP + jnz LookupLoop1 + AFTER_JMP + + +//;;; Store the current value of chainlen. + mov [chainlenwmask], edx +/* +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). +*/ + lea rsi,[r8+r10] + mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8) + lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8] + lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8] + + prefetcht1 [rsi+rdx] + prefetcht1 [rdi+rdx] + +/* +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust rdx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (rsi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. +*/ + +LoopCmps: + mov rax, [rsi + rdx] + xor rax, [rdi + rdx] + jnz LeaveLoopCmps + + mov rax, [rsi + rdx + 8] + xor rax, [rdi + rdx + 8] + jnz LeaveLoopCmps8 + + + mov rax, [rsi + rdx + 8+8] + xor rax, [rdi + rdx + 8+8] + jnz LeaveLoopCmps16 + + add rdx,8+8+8 + + BEFORE_JMP + jnz LoopCmps + jmp LenMaximum + AFTER_JMP + +LeaveLoopCmps16: add rdx,8 +LeaveLoopCmps8: add rdx,8 +LeaveLoopCmps: + + test eax, 0x0000FFFF + jnz LenLower + + test eax,0xffffffff + + jnz LenLower32 + + add rdx,4 + shr rax,32 + or ax,ax + BEFORE_JMP + jnz LenLower + AFTER_JMP + +LenLower32: + shr eax,16 + add rdx,2 + +LenLower: + sub al, 1 + adc rdx, 0 +//;;; Calculate the length of the match. If it is longer than MAX_MATCH, +//;;; then automatically accept it as the best possible match and leave. + + lea rax, [rdi + rdx] + sub rax, r9 + cmp eax, MAX_MATCH + BEFORE_JMP + jge LenMaximum + AFTER_JMP +/* +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. +;/////////////////////////////////// +*/ + cmp eax, r11d + jg LongerMatch + + lea rsi,[r10+r11] + + mov rdi, prev_ad + mov edx, [chainlenwmask] + BEFORE_JMP + jmp LookupLoop + AFTER_JMP +/* +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); +*/ +LongerMatch: + mov r11d, eax + mov match_start, r8d + cmp eax, [nicematch] + BEFORE_JMP + jge LeaveNow + AFTER_JMP + + lea rsi,[r10+rax] + + movzx ebx, word ptr [r9 + rax - 1] + mov rdi, prev_ad + mov edx, [chainlenwmask] + BEFORE_JMP + jmp LookupLoop + AFTER_JMP + +//;;; Accept the current string, with the maximum possible length. + +LenMaximum: + mov r11d,MAX_MATCH + mov match_start, r8d + +//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +//;;; return s->lookahead; + +LeaveNow: + mov eax, Lookahead + cmp r11d, eax + cmovng eax, r11d + + + +//;;; Restore the stack and return from whence we came. + + +// mov rsi,[save_rsi] +// mov rdi,[save_rdi] + mov rbx,[save_rbx] + mov rbp,[save_rbp] + mov r12,[save_r12] + mov r13,[save_r13] + mov r14,[save_r14] + mov r15,[save_r15] + + + ret 0 +//; please don't remove this string ! +//; Your can freely use gvmat64 in any free or commercial app +//; but it is far better don't remove the string in the binary! + // db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0 + + +match_init: + ret 0 + + diff --git a/libz/contrib/infback9/README b/libz/contrib/infback9/README new file mode 100644 index 000000000..e75ed1329 --- /dev/null +++ b/libz/contrib/infback9/README @@ -0,0 +1 @@ +See infback9.h for what this is and how to use it. diff --git a/libz/contrib/infback9/infback9.c b/libz/contrib/infback9/infback9.c new file mode 100644 index 000000000..05fb3e338 --- /dev/null +++ b/libz/contrib/infback9/infback9.c @@ -0,0 +1,615 @@ +/* infback9.c -- inflate deflate64 data using a call-back interface + * Copyright (C) 1995-2008 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infback9.h" +#include "inftree9.h" +#include "inflate9.h" + +#define WSIZE 65536UL + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + window is a user-supplied window and output buffer that is 64K bytes. + */ +int ZEXPORT inflateBack9Init_(strm, window, version, stream_size) +z_stream FAR *strm; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (voidpf)state; + state->window = window; + return Z_OK; +} + +/* + Build and output length and distance decoding tables for fixed code + decoding. + */ +#ifdef MAKEFIXED +#include + +void makefixed9(void) +{ + unsigned sym, bits, low, size; + code *next, *lenfix, *distfix; + struct inflate_state state; + code fixed[544]; + + /* literal/length table */ + sym = 0; + while (sym < 144) state.lens[sym++] = 8; + while (sym < 256) state.lens[sym++] = 9; + while (sym < 280) state.lens[sym++] = 7; + while (sym < 288) state.lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work); + + /* distance table */ + sym = 0; + while (sym < 32) state.lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work); + + /* write tables */ + puts(" /* inffix9.h -- table for decoding deflate64 fixed codes"); + puts(" * Generated automatically by makefixed9()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits, + lenfix[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 5) == 0) printf("\n "); + printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits, + distfix[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* Macros for inflateBack(): */ + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n <= 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = window; \ + left = WSIZE; \ + wrap = 1; \ + if (out(out_desc, put, (unsigned)left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc) +z_stream FAR *strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have; /* available input */ + unsigned long left; /* available output */ + inflate_mode mode; /* current inflate mode */ + int lastblock; /* true if processing last block */ + int wrap; /* true if the window has wrapped */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned extra; /* extra bits needed */ + unsigned long length; /* literal or length of data to copy */ + unsigned long offset; /* distance back to copy string from */ + unsigned long copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +#include "inffix9.h" + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + mode = TYPE; + lastblock = 0; + wrap = 0; + window = state->window; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = window; + left = WSIZE; + lencode = Z_NULL; + distcode = Z_NULL; + + /* Inflate until end of block marked as last */ + for (;;) + switch (mode) { + case TYPE: + /* determine and dispatch block type */ + if (lastblock) { + BYTEBITS(); + mode = DONE; + break; + } + NEEDBITS(3); + lastblock = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + lastblock ? " (last)" : "")); + mode = STORED; + break; + case 1: /* fixed block */ + lencode = lenfix; + lenbits = 9; + distcode = distfix; + distbits = 5; + Tracev((stderr, "inflate: fixed codes block%s\n", + lastblock ? " (last)" : "")); + mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + lastblock ? " (last)" : "")); + mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + mode = BAD; + break; + } + length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %lu\n", + length)); + INITBITS(); + + /* copy stored block from input to output */ + while (length != 0) { + copy = length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); + if (state->nlen > 286) { + strm->msg = (char *)"too many length symbols"; + mode = BAD; + break; + } + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + lencode = (code const FAR *)(state->next); + lenbits = 7; + ret = inflate_table9(CODES, state->lens, 19, &(state->next), + &(lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = lencode[BITS(lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftree9.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + lencode = (code const FAR *)(state->next); + lenbits = 9; + ret = inflate_table9(LENS, state->lens, state->nlen, + &(state->next), &(lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + mode = BAD; + break; + } + distcode = (code const FAR *)(state->next); + distbits = 6; + ret = inflate_table9(DISTS, state->lens + state->nlen, + state->ndist, &(state->next), &(distbits), + state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + mode = LEN; + + case LEN: + /* get a literal, length, or end-of-block code */ + for (;;) { + here = lencode[BITS(lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(length); + left--; + mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + extra = (unsigned)(here.op) & 31; + if (extra != 0) { + NEEDBITS(extra); + length += BITS(extra); + DROPBITS(extra); + } + Tracevv((stderr, "inflate: length %lu\n", length)); + + /* get distance code */ + for (;;) { + here = distcode[BITS(distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + mode = BAD; + break; + } + offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + extra = (unsigned)(here.op) & 15; + if (extra != 0) { + NEEDBITS(extra); + offset += BITS(extra); + DROPBITS(extra); + } + if (offset > WSIZE - (wrap ? 0: left)) { + strm->msg = (char *)"invalid distance too far back"; + mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %lu\n", offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = WSIZE - offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - offset; + copy = left; + } + if (copy > length) copy = length; + length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < WSIZE) { + if (out(out_desc, window, (unsigned)(WSIZE - left))) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBack9End(strm) +z_stream FAR *strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/libz/contrib/infback9/infback9.h b/libz/contrib/infback9/infback9.h new file mode 100644 index 000000000..1073c0a38 --- /dev/null +++ b/libz/contrib/infback9/infback9.h @@ -0,0 +1,37 @@ +/* infback9.h -- header for using inflateBack9 functions + * Copyright (C) 2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * This header file and associated patches provide a decoder for PKWare's + * undocumented deflate64 compression method (method 9). Use with infback9.c, + * inftree9.h, inftree9.c, and inffix9.h. These patches are not supported. + * This should be compiled with zlib, since it uses zutil.h and zutil.o. + * This code has not yet been tested on 16-bit architectures. See the + * comments in zlib.h for inflateBack() usage. These functions are used + * identically, except that there is no windowBits parameter, and a 64K + * window must be provided. Also if int's are 16 bits, then a zero for + * the third parameter of the "out" function actually means 65536UL. + * zlib.h must be included before this header file. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +ZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm)); +ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define inflateBack9Init(strm, window) \ + inflateBack9Init_((strm), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +#ifdef __cplusplus +} +#endif diff --git a/libz/contrib/infback9/inffix9.h b/libz/contrib/infback9/inffix9.h new file mode 100644 index 000000000..ee5671d2d --- /dev/null +++ b/libz/contrib/infback9/inffix9.h @@ -0,0 +1,107 @@ + /* inffix9.h -- table for decoding deflate64 fixed codes + * Generated automatically by makefixed9(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112}, + {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160}, + {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88}, + {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208}, + {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136}, + {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227}, + {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232}, + {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124}, + {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184}, + {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82}, + {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196}, + {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130}, + {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148}, + {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106}, + {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244}, + {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118}, + {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172}, + {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94}, + {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220}, + {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131}, + {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97}, + {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226}, + {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121}, + {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178}, + {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85}, + {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202}, + {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133}, + {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154}, + {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109}, + {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250}, + {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115}, + {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166}, + {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91}, + {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214}, + {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139}, + {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0}, + {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103}, + {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238}, + {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127}, + {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80}, + {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193}, + {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128}, + {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145}, + {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104}, + {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241}, + {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116}, + {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169}, + {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92}, + {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217}, + {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140}, + {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163}, + {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98}, + {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122}, + {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181}, + {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86}, + {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205}, + {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134}, + {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157}, + {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253}, + {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113}, + {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163}, + {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89}, + {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211}, + {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137}, + {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3}, + {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101}, + {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235}, + {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125}, + {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187}, + {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83}, + {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199}, + {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151}, + {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107}, + {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247}, + {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119}, + {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175}, + {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95}, + {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223}, + {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143}, + {0,8,79},{0,9,255} + }; + + static const code distfix[32] = { + {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5}, + {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513}, + {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129}, + {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145}, + {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4}, + {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073}, + {134,5,193},{142,5,49153} + }; diff --git a/libz/contrib/infback9/inflate9.h b/libz/contrib/infback9/inflate9.h new file mode 100644 index 000000000..ee9a79394 --- /dev/null +++ b/libz/contrib/infback9/inflate9.h @@ -0,0 +1,47 @@ +/* inflate9.h -- internal inflate state definition + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Possible inflate modes between inflate() calls */ +typedef enum { + TYPE, /* i: waiting for type bits, including last-flag bit */ + STORED, /* i: waiting for stored size (length and complement) */ + TABLE, /* i: waiting for dynamic block table lengths */ + LEN, /* i: waiting for length/lit code */ + DONE, /* finished check, done -- remain here until reset */ + BAD /* got a data error -- remain here until reset */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD mode -- not shown for clarity) + + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or DONE + STORED -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LEN or TYPE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + /* sliding window */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/libz/contrib/infback9/inftree9.c b/libz/contrib/infback9/inftree9.c new file mode 100644 index 000000000..4a73ad215 --- /dev/null +++ b/libz/contrib/infback9/inftree9.c @@ -0,0 +1,324 @@ +/* inftree9.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftree9.h" + +#define MAXBITS 15 + +const char inflate9_copyright[] = + " inflate9 1.2.8 Copyright 1995-2013 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table9(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, + 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, + 131, 163, 195, 227, 3, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, + 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, + 133, 133, 133, 133, 144, 72, 78}; + static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, + 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, + 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153}; + static const unsigned short dext[32] = { /* Distance codes 0..31 extra */ + 128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, + 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138, + 139, 139, 140, 140, 141, 141, 142, 142}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) return -1; /* no codes! */ + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftree9.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += 1U << curr; + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + curr = root; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/libz/contrib/infback9/inftree9.h b/libz/contrib/infback9/inftree9.h new file mode 100644 index 000000000..5ab21f0c6 --- /dev/null +++ b/libz/contrib/infback9/inftree9.h @@ -0,0 +1,61 @@ +/* inftree9.h -- header to use inftree9.c + * Copyright (C) 1995-2008 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 100eeeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1446, which is the sum of 852 for literal/length codes and 594 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 32 6 15" for distance codes returns 594. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in infback9.c. If the root table size is changed, + then these maximum sizes would be need to be recalculated and updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 594 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table9() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table9 OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/libz/contrib/inflate86/inffas86.c b/libz/contrib/inflate86/inffas86.c new file mode 100644 index 000000000..7292f67b7 --- /dev/null +++ b/libz/contrib/inflate86/inffas86.c @@ -0,0 +1,1157 @@ +/* inffas86.c is a hand tuned assembler version of + * + * inffast.c -- fast decoding + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also + * slightly quicker on x86 systems because, instead of using rep movsb to copy + * data, it uses rep movsw, which moves data in 2-byte chunks instead of single + * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates + * from http://fedora.linux.duke.edu/fc1_x86_64 + * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with + * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version, + * when decompressing mozilla-source-1.3.tar.gz. + * + * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from + * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at + * the moment. I have successfully compiled and tested this code with gcc2.96, + * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S + * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX + * enabled. I will attempt to merge the MMX code into this version. Newer + * versions of this and inffast.S can be found at + * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* Mark Adler's comments from inffast.c: */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + struct inffast_ar { +/* 64 32 x86 x86_64 */ +/* ar offset register */ +/* 0 0 */ void *esp; /* esp save */ +/* 8 4 */ void *ebp; /* ebp save */ +/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */ +/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */ +/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */ +/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */ +/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */ +/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */ +/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */ +/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */ +/* 80 40 */ unsigned long hold; /* edx rdx local strm->hold */ +/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */ +/* 92 48 */ unsigned wsize; /* window size */ +/* 96 52 */ unsigned write; /* window write index */ +/*100 56 */ unsigned lmask; /* r12 mask for lcode */ +/*104 60 */ unsigned dmask; /* r13 mask for dcode */ +/*108 64 */ unsigned len; /* r14 match length */ +/*112 68 */ unsigned dist; /* r15 match distance */ +/*116 72 */ unsigned status; /* set when state chng*/ + } ar; + +#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 ) +#define PAD_AVAIL_IN 6 +#define PAD_AVAIL_OUT 258 +#else +#define PAD_AVAIL_IN 5 +#define PAD_AVAIL_OUT 257 +#endif + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + ar.in = strm->next_in; + ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN); + ar.out = strm->next_out; + ar.beg = ar.out - (start - strm->avail_out); + ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT); + ar.wsize = state->wsize; + ar.write = state->wnext; + ar.window = state->window; + ar.hold = state->hold; + ar.bits = state->bits; + ar.lcode = state->lencode; + ar.dcode = state->distcode; + ar.lmask = (1U << state->lenbits) - 1; + ar.dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + /* align in on 1/2 hold size boundary */ + while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) { + ar.hold += (unsigned long)*ar.in++ << ar.bits; + ar.bits += 8; + } + +#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 ) + __asm__ __volatile__ ( +" leaq %0, %%rax\n" +" movq %%rbp, 8(%%rax)\n" /* save regs rbp and rsp */ +" movq %%rsp, (%%rax)\n" +" movq %%rax, %%rsp\n" /* make rsp point to &ar */ +" movq 16(%%rsp), %%rsi\n" /* rsi = in */ +" movq 32(%%rsp), %%rdi\n" /* rdi = out */ +" movq 24(%%rsp), %%r9\n" /* r9 = last */ +" movq 48(%%rsp), %%r10\n" /* r10 = end */ +" movq 64(%%rsp), %%rbp\n" /* rbp = lcode */ +" movq 72(%%rsp), %%r11\n" /* r11 = dcode */ +" movq 80(%%rsp), %%rdx\n" /* rdx = hold */ +" movl 88(%%rsp), %%ebx\n" /* ebx = bits */ +" movl 100(%%rsp), %%r12d\n" /* r12d = lmask */ +" movl 104(%%rsp), %%r13d\n" /* r13d = dmask */ + /* r14d = len */ + /* r15d = dist */ +" cld\n" +" cmpq %%rdi, %%r10\n" +" je .L_one_time\n" /* if only one decode left */ +" cmpq %%rsi, %%r9\n" +" je .L_one_time\n" +" jmp .L_do_loop\n" + +".L_one_time:\n" +" movq %%r12, %%r8\n" /* r8 = lmask */ +" cmpb $32, %%bl\n" +" ja .L_get_length_code_one_time\n" + +" lodsl\n" /* eax = *(uint *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $32, %%bl\n" /* bits += 32 */ +" shlq %%cl, %%rax\n" +" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */ +" jmp .L_get_length_code_one_time\n" + +".align 32,0x90\n" +".L_while_test:\n" +" cmpq %%rdi, %%r10\n" +" jbe .L_break_loop\n" +" cmpq %%rsi, %%r9\n" +" jbe .L_break_loop\n" + +".L_do_loop:\n" +" movq %%r12, %%r8\n" /* r8 = lmask */ +" cmpb $32, %%bl\n" +" ja .L_get_length_code\n" /* if (32 < bits) */ + +" lodsl\n" /* eax = *(uint *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $32, %%bl\n" /* bits += 32 */ +" shlq %%cl, %%rax\n" +" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */ + +".L_get_length_code:\n" +" andq %%rdx, %%r8\n" /* r8 &= hold */ +" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */ + +" movb %%ah, %%cl\n" /* cl = this.bits */ +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrq %%cl, %%rdx\n" /* hold >>= this.bits */ + +" testb %%al, %%al\n" +" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */ + +" movq %%r12, %%r8\n" /* r8 = lmask */ +" shrl $16, %%eax\n" /* output this.val char */ +" stosb\n" + +".L_get_length_code_one_time:\n" +" andq %%rdx, %%r8\n" /* r8 &= hold */ +" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */ + +".L_dolen:\n" +" movb %%ah, %%cl\n" /* cl = this.bits */ +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrq %%cl, %%rdx\n" /* hold >>= this.bits */ + +" testb %%al, %%al\n" +" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */ + +" shrl $16, %%eax\n" /* output this.val char */ +" stosb\n" +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_length_base:\n" +" movl %%eax, %%r14d\n" /* len = this */ +" shrl $16, %%r14d\n" /* len = this.val */ +" movb %%al, %%cl\n" + +" testb $16, %%al\n" +" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */ +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_decode_distance\n" /* if (!op) */ + +".L_add_bits_to_len:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrq %%cl, %%rdx\n" +" addl %%eax, %%r14d\n" /* len += hold & mask[op] */ + +".L_decode_distance:\n" +" movq %%r13, %%r8\n" /* r8 = dmask */ +" cmpb $32, %%bl\n" +" ja .L_get_distance_code\n" /* if (32 < bits) */ + +" lodsl\n" /* eax = *(uint *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $32, %%bl\n" /* bits += 32 */ +" shlq %%cl, %%rax\n" +" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */ + +".L_get_distance_code:\n" +" andq %%rdx, %%r8\n" /* r8 &= hold */ +" movl (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */ + +".L_dodist:\n" +" movl %%eax, %%r15d\n" /* dist = this */ +" shrl $16, %%r15d\n" /* dist = this.val */ +" movb %%ah, %%cl\n" +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrq %%cl, %%rdx\n" /* hold >>= this.bits */ +" movb %%al, %%cl\n" /* cl = this.op */ + +" testb $16, %%al\n" /* if ((op & 16) == 0) */ +" jz .L_test_for_second_level_dist\n" +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_check_dist_one\n" + +".L_add_bits_to_dist:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" /* (1 << op) - 1 */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrq %%cl, %%rdx\n" +" addl %%eax, %%r15d\n" /* dist += hold & ((1 << op) - 1) */ + +".L_check_window:\n" +" movq %%rsi, %%r8\n" /* save in so from can use it's reg */ +" movq %%rdi, %%rax\n" +" subq 40(%%rsp), %%rax\n" /* nbytes = out - beg */ + +" cmpl %%r15d, %%eax\n" +" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */ + +" movl %%r14d, %%ecx\n" /* ecx = len */ +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = out - dist */ + +" sarl %%ecx\n" +" jnc .L_copy_two\n" /* if len % 2 == 0 */ + +" rep movsw\n" +" movb (%%rsi), %%al\n" +" movb %%al, (%%rdi)\n" +" incq %%rdi\n" + +" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */ +" jmp .L_while_test\n" + +".L_copy_two:\n" +" rep movsw\n" +" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */ +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_check_dist_one:\n" +" cmpl $1, %%r15d\n" /* if dist 1, is a memset */ +" jne .L_check_window\n" +" cmpq %%rdi, 40(%%rsp)\n" /* if out == beg, outside window */ +" je .L_check_window\n" + +" movl %%r14d, %%ecx\n" /* ecx = len */ +" movb -1(%%rdi), %%al\n" +" movb %%al, %%ah\n" + +" sarl %%ecx\n" +" jnc .L_set_two\n" +" movb %%al, (%%rdi)\n" +" incq %%rdi\n" + +".L_set_two:\n" +" rep stosw\n" +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_second_level_length:\n" +" testb $64, %%al\n" +" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl %%r14d, %%eax\n" /* eax += len */ +" movl (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/ +" jmp .L_dolen\n" + +".align 32,0x90\n" +".L_test_for_second_level_dist:\n" +" testb $64, %%al\n" +" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl %%r15d, %%eax\n" /* eax += dist */ +" movl (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/ +" jmp .L_dodist\n" + +".align 32,0x90\n" +".L_clip_window:\n" +" movl %%eax, %%ecx\n" /* ecx = nbytes */ +" movl 92(%%rsp), %%eax\n" /* eax = wsize, prepare for dist cmp */ +" negl %%ecx\n" /* nbytes = -nbytes */ + +" cmpl %%r15d, %%eax\n" +" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */ + +" addl %%r15d, %%ecx\n" /* nbytes = dist - nbytes */ +" cmpl $0, 96(%%rsp)\n" +" jne .L_wrap_around_window\n" /* if (write != 0) */ + +" movq 56(%%rsp), %%rsi\n" /* from = window */ +" subl %%ecx, %%eax\n" /* eax -= nbytes */ +" addq %%rax, %%rsi\n" /* from += wsize - nbytes */ + +" movl %%r14d, %%eax\n" /* eax = len */ +" cmpl %%ecx, %%r14d\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* eax -= nbytes */ +" rep movsb\n" +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = &out[ -dist ] */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_wrap_around_window:\n" +" movl 96(%%rsp), %%eax\n" /* eax = write */ +" cmpl %%eax, %%ecx\n" +" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */ + +" movl 92(%%rsp), %%esi\n" /* from = wsize */ +" addq 56(%%rsp), %%rsi\n" /* from += window */ +" addq %%rax, %%rsi\n" /* from += write */ +" subq %%rcx, %%rsi\n" /* from -= nbytes */ +" subl %%eax, %%ecx\n" /* nbytes -= write */ + +" movl %%r14d, %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movq 56(%%rsp), %%rsi\n" /* from = window */ +" movl 96(%%rsp), %%ecx\n" /* nbytes = write */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = out - dist */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_contiguous_in_window:\n" +" movq 56(%%rsp), %%rsi\n" /* rsi = window */ +" addq %%rax, %%rsi\n" +" subq %%rcx, %%rsi\n" /* from += write - nbytes */ + +" movl %%r14d, %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movq %%rdi, %%rsi\n" +" subq %%r15, %%rsi\n" /* from = out - dist */ +" jmp .L_do_copy\n" /* if (nbytes >= len) */ + +".align 32,0x90\n" +".L_do_copy:\n" +" movl %%eax, %%ecx\n" /* ecx = len */ +" rep movsb\n" + +" movq %%r8, %%rsi\n" /* move in back to %esi, toss from */ +" jmp .L_while_test\n" + +".L_test_for_end_of_block:\n" +" testb $32, %%al\n" +" jz .L_invalid_literal_length_code\n" +" movl $1, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_literal_length_code:\n" +" movl $2, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_code:\n" +" movl $3, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_too_far:\n" +" movl $4, 116(%%rsp)\n" +" jmp .L_break_loop_with_status\n" + +".L_break_loop:\n" +" movl $0, 116(%%rsp)\n" + +".L_break_loop_with_status:\n" +/* put in, out, bits, and hold back into ar and pop esp */ +" movq %%rsi, 16(%%rsp)\n" /* in */ +" movq %%rdi, 32(%%rsp)\n" /* out */ +" movl %%ebx, 88(%%rsp)\n" /* bits */ +" movq %%rdx, 80(%%rsp)\n" /* hold */ +" movq (%%rsp), %%rax\n" /* restore rbp and rsp */ +" movq 8(%%rsp), %%rbp\n" +" movq %%rax, %%rsp\n" + : + : "m" (ar) + : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" + ); +#elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 ) + __asm__ __volatile__ ( +" leal %0, %%eax\n" +" movl %%esp, (%%eax)\n" /* save esp, ebp */ +" movl %%ebp, 4(%%eax)\n" +" movl %%eax, %%esp\n" +" movl 8(%%esp), %%esi\n" /* esi = in */ +" movl 16(%%esp), %%edi\n" /* edi = out */ +" movl 40(%%esp), %%edx\n" /* edx = hold */ +" movl 44(%%esp), %%ebx\n" /* ebx = bits */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ + +" cld\n" +" jmp .L_do_loop\n" + +".align 32,0x90\n" +".L_while_test:\n" +" cmpl %%edi, 24(%%esp)\n" /* out < end */ +" jbe .L_break_loop\n" +" cmpl %%esi, 12(%%esp)\n" /* in < last */ +" jbe .L_break_loop\n" + +".L_do_loop:\n" +" cmpb $15, %%bl\n" +" ja .L_get_length_code\n" /* if (15 < bits) */ + +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ + +".L_get_length_code:\n" +" movl 56(%%esp), %%eax\n" /* eax = lmask */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */ + +".L_dolen:\n" +" movb %%ah, %%cl\n" /* cl = this.bits */ +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrl %%cl, %%edx\n" /* hold >>= this.bits */ + +" testb %%al, %%al\n" +" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */ + +" shrl $16, %%eax\n" /* output this.val char */ +" stosb\n" +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_length_base:\n" +" movl %%eax, %%ecx\n" /* len = this */ +" shrl $16, %%ecx\n" /* len = this.val */ +" movl %%ecx, 64(%%esp)\n" /* save len */ +" movb %%al, %%cl\n" + +" testb $16, %%al\n" +" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */ +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_decode_distance\n" /* if (!op) */ +" cmpb %%cl, %%bl\n" +" jae .L_add_bits_to_len\n" /* if (op <= bits) */ + +" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */ +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ +" movb %%ch, %%cl\n" /* move op back to ecx */ + +".L_add_bits_to_len:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrl %%cl, %%edx\n" +" addl %%eax, 64(%%esp)\n" /* len += hold & mask[op] */ + +".L_decode_distance:\n" +" cmpb $15, %%bl\n" +" ja .L_get_distance_code\n" /* if (15 < bits) */ + +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ + +".L_get_distance_code:\n" +" movl 60(%%esp), %%eax\n" /* eax = dmask */ +" movl 36(%%esp), %%ecx\n" /* ecx = dcode */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */ + +".L_dodist:\n" +" movl %%eax, %%ebp\n" /* dist = this */ +" shrl $16, %%ebp\n" /* dist = this.val */ +" movb %%ah, %%cl\n" +" subb %%ah, %%bl\n" /* bits -= this.bits */ +" shrl %%cl, %%edx\n" /* hold >>= this.bits */ +" movb %%al, %%cl\n" /* cl = this.op */ + +" testb $16, %%al\n" /* if ((op & 16) == 0) */ +" jz .L_test_for_second_level_dist\n" +" andb $15, %%cl\n" /* op &= 15 */ +" jz .L_check_dist_one\n" +" cmpb %%cl, %%bl\n" +" jae .L_add_bits_to_dist\n" /* if (op <= bits) 97.6% */ + +" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */ +" xorl %%eax, %%eax\n" +" lodsw\n" /* al = *(ushort *)in++ */ +" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */ +" addb $16, %%bl\n" /* bits += 16 */ +" shll %%cl, %%eax\n" +" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ +" movb %%ch, %%cl\n" /* move op back to ecx */ + +".L_add_bits_to_dist:\n" +" subb %%cl, %%bl\n" +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" /* (1 << op) - 1 */ +" andl %%edx, %%eax\n" /* eax &= hold */ +" shrl %%cl, %%edx\n" +" addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */ + +".L_check_window:\n" +" movl %%esi, 8(%%esp)\n" /* save in so from can use it's reg */ +" movl %%edi, %%eax\n" +" subl 20(%%esp), %%eax\n" /* nbytes = out - beg */ + +" cmpl %%ebp, %%eax\n" +" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */ + +" movl 64(%%esp), %%ecx\n" /* ecx = len */ +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ + +" sarl %%ecx\n" +" jnc .L_copy_two\n" /* if len % 2 == 0 */ + +" rep movsw\n" +" movb (%%esi), %%al\n" +" movb %%al, (%%edi)\n" +" incl %%edi\n" + +" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".L_copy_two:\n" +" rep movsw\n" +" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_check_dist_one:\n" +" cmpl $1, %%ebp\n" /* if dist 1, is a memset */ +" jne .L_check_window\n" +" cmpl %%edi, 20(%%esp)\n" +" je .L_check_window\n" /* out == beg, if outside window */ + +" movl 64(%%esp), %%ecx\n" /* ecx = len */ +" movb -1(%%edi), %%al\n" +" movb %%al, %%ah\n" + +" sarl %%ecx\n" +" jnc .L_set_two\n" +" movb %%al, (%%edi)\n" +" incl %%edi\n" + +".L_set_two:\n" +" rep stosw\n" +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".align 32,0x90\n" +".L_test_for_second_level_length:\n" +" testb $64, %%al\n" +" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl 64(%%esp), %%eax\n" /* eax += len */ +" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/ +" jmp .L_dolen\n" + +".align 32,0x90\n" +".L_test_for_second_level_dist:\n" +" testb $64, %%al\n" +" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */ + +" xorl %%eax, %%eax\n" +" incl %%eax\n" +" shll %%cl, %%eax\n" +" decl %%eax\n" +" andl %%edx, %%eax\n" /* eax &= hold */ +" addl %%ebp, %%eax\n" /* eax += dist */ +" movl 36(%%esp), %%ecx\n" /* ecx = dcode */ +" movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/ +" jmp .L_dodist\n" + +".align 32,0x90\n" +".L_clip_window:\n" +" movl %%eax, %%ecx\n" +" movl 48(%%esp), %%eax\n" /* eax = wsize */ +" negl %%ecx\n" /* nbytes = -nbytes */ +" movl 28(%%esp), %%esi\n" /* from = window */ + +" cmpl %%ebp, %%eax\n" +" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */ + +" addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */ +" cmpl $0, 52(%%esp)\n" +" jne .L_wrap_around_window\n" /* if (write != 0) */ + +" subl %%ecx, %%eax\n" +" addl %%eax, %%esi\n" /* from += wsize - nbytes */ + +" movl 64(%%esp), %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_wrap_around_window:\n" +" movl 52(%%esp), %%eax\n" /* eax = write */ +" cmpl %%eax, %%ecx\n" +" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */ + +" addl 48(%%esp), %%esi\n" /* from += wsize */ +" addl %%eax, %%esi\n" /* from += write */ +" subl %%ecx, %%esi\n" /* from -= nbytes */ +" subl %%eax, %%ecx\n" /* nbytes -= write */ + +" movl 64(%%esp), %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl 28(%%esp), %%esi\n" /* from = window */ +" movl 52(%%esp), %%ecx\n" /* nbytes = write */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ +" jmp .L_do_copy\n" + +".align 32,0x90\n" +".L_contiguous_in_window:\n" +" addl %%eax, %%esi\n" +" subl %%ecx, %%esi\n" /* from += write - nbytes */ + +" movl 64(%%esp), %%eax\n" /* eax = len */ +" cmpl %%ecx, %%eax\n" +" jbe .L_do_copy\n" /* if (nbytes >= len) */ + +" subl %%ecx, %%eax\n" /* len -= nbytes */ +" rep movsb\n" +" movl %%edi, %%esi\n" +" subl %%ebp, %%esi\n" /* from = out - dist */ +" jmp .L_do_copy\n" /* if (nbytes >= len) */ + +".align 32,0x90\n" +".L_do_copy:\n" +" movl %%eax, %%ecx\n" +" rep movsb\n" + +" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */ +" movl 32(%%esp), %%ebp\n" /* ebp = lcode */ +" jmp .L_while_test\n" + +".L_test_for_end_of_block:\n" +" testb $32, %%al\n" +" jz .L_invalid_literal_length_code\n" +" movl $1, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_literal_length_code:\n" +" movl $2, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_code:\n" +" movl $3, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_invalid_distance_too_far:\n" +" movl 8(%%esp), %%esi\n" +" movl $4, 72(%%esp)\n" +" jmp .L_break_loop_with_status\n" + +".L_break_loop:\n" +" movl $0, 72(%%esp)\n" + +".L_break_loop_with_status:\n" +/* put in, out, bits, and hold back into ar and pop esp */ +" movl %%esi, 8(%%esp)\n" /* save in */ +" movl %%edi, 16(%%esp)\n" /* save out */ +" movl %%ebx, 44(%%esp)\n" /* save bits */ +" movl %%edx, 40(%%esp)\n" /* save hold */ +" movl 4(%%esp), %%ebp\n" /* restore esp, ebp */ +" movl (%%esp), %%esp\n" + : + : "m" (ar) + : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" + ); +#elif defined( _MSC_VER ) && ! defined( _M_AMD64 ) + __asm { + lea eax, ar + mov [eax], esp /* save esp, ebp */ + mov [eax+4], ebp + mov esp, eax + mov esi, [esp+8] /* esi = in */ + mov edi, [esp+16] /* edi = out */ + mov edx, [esp+40] /* edx = hold */ + mov ebx, [esp+44] /* ebx = bits */ + mov ebp, [esp+32] /* ebp = lcode */ + + cld + jmp L_do_loop + +ALIGN 4 +L_while_test: + cmp [esp+24], edi + jbe L_break_loop + cmp [esp+12], esi + jbe L_break_loop + +L_do_loop: + cmp bl, 15 + ja L_get_length_code /* if (15 < bits) */ + + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + +L_get_length_code: + mov eax, [esp+56] /* eax = lmask */ + and eax, edx /* eax &= hold */ + mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */ + +L_dolen: + mov cl, ah /* cl = this.bits */ + sub bl, ah /* bits -= this.bits */ + shr edx, cl /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base /* if (op != 0) 45.7% */ + + shr eax, 16 /* output this.val char */ + stosb + jmp L_while_test + +ALIGN 4 +L_test_for_length_base: + mov ecx, eax /* len = this */ + shr ecx, 16 /* len = this.val */ + mov [esp+64], ecx /* save len */ + mov cl, al + + test al, 16 + jz L_test_for_second_level_length /* if ((op & 16) == 0) 8% */ + and cl, 15 /* op &= 15 */ + jz L_decode_distance /* if (!op) */ + cmp bl, cl + jae L_add_bits_to_len /* if (op <= bits) */ + + mov ch, cl /* stash op in ch, freeing cl */ + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + mov cl, ch /* move op back to ecx */ + +L_add_bits_to_len: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx /* eax &= hold */ + shr edx, cl + add [esp+64], eax /* len += hold & mask[op] */ + +L_decode_distance: + cmp bl, 15 + ja L_get_distance_code /* if (15 < bits) */ + + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + +L_get_distance_code: + mov eax, [esp+60] /* eax = dmask */ + mov ecx, [esp+36] /* ecx = dcode */ + and eax, edx /* eax &= hold */ + mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */ + +L_dodist: + mov ebp, eax /* dist = this */ + shr ebp, 16 /* dist = this.val */ + mov cl, ah + sub bl, ah /* bits -= this.bits */ + shr edx, cl /* hold >>= this.bits */ + mov cl, al /* cl = this.op */ + + test al, 16 /* if ((op & 16) == 0) */ + jz L_test_for_second_level_dist + and cl, 15 /* op &= 15 */ + jz L_check_dist_one + cmp bl, cl + jae L_add_bits_to_dist /* if (op <= bits) 97.6% */ + + mov ch, cl /* stash op in ch, freeing cl */ + xor eax, eax + lodsw /* al = *(ushort *)in++ */ + mov cl, bl /* cl = bits, needs it for shifting */ + add bl, 16 /* bits += 16 */ + shl eax, cl + or edx, eax /* hold |= *((ushort *)in)++ << bits */ + mov cl, ch /* move op back to ecx */ + +L_add_bits_to_dist: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax /* (1 << op) - 1 */ + and eax, edx /* eax &= hold */ + shr edx, cl + add ebp, eax /* dist += hold & ((1 << op) - 1) */ + +L_check_window: + mov [esp+8], esi /* save in so from can use it's reg */ + mov eax, edi + sub eax, [esp+20] /* nbytes = out - beg */ + + cmp eax, ebp + jb L_clip_window /* if (dist > nbytes) 4.2% */ + + mov ecx, [esp+64] /* ecx = len */ + mov esi, edi + sub esi, ebp /* from = out - dist */ + + sar ecx, 1 + jnc L_copy_two + + rep movsw + mov al, [esi] + mov [edi], al + inc edi + + mov esi, [esp+8] /* move in back to %esi, toss from */ + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +L_copy_two: + rep movsw + mov esi, [esp+8] /* move in back to %esi, toss from */ + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp ebp, 1 /* if dist 1, is a memset */ + jne L_check_window + cmp [esp+20], edi + je L_check_window /* out == beg, if outside window */ + + mov ecx, [esp+64] /* ecx = len */ + mov al, [edi-1] + mov ah, al + + sar ecx, 1 + jnc L_set_two + mov [edi], al /* memset out with from[-1] */ + inc edi + +L_set_two: + rep stosw + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + test al, 64 + jnz L_test_for_end_of_block /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx /* eax &= hold */ + add eax, [esp+64] /* eax += len */ + mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/ + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + test al, 64 + jnz L_invalid_distance_code /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx /* eax &= hold */ + add eax, ebp /* eax += dist */ + mov ecx, [esp+36] /* ecx = dcode */ + mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/ + jmp L_dodist + +ALIGN 4 +L_clip_window: + mov ecx, eax + mov eax, [esp+48] /* eax = wsize */ + neg ecx /* nbytes = -nbytes */ + mov esi, [esp+28] /* from = window */ + + cmp eax, ebp + jb L_invalid_distance_too_far /* if (dist > wsize) */ + + add ecx, ebp /* nbytes = dist - nbytes */ + cmp dword ptr [esp+52], 0 + jne L_wrap_around_window /* if (write != 0) */ + + sub eax, ecx + add esi, eax /* from += wsize - nbytes */ + + mov eax, [esp+64] /* eax = len */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, edi + sub esi, ebp /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_wrap_around_window: + mov eax, [esp+52] /* eax = write */ + cmp ecx, eax + jbe L_contiguous_in_window /* if (write >= nbytes) */ + + add esi, [esp+48] /* from += wsize */ + add esi, eax /* from += write */ + sub esi, ecx /* from -= nbytes */ + sub ecx, eax /* nbytes -= write */ + + mov eax, [esp+64] /* eax = len */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, [esp+28] /* from = window */ + mov ecx, [esp+52] /* nbytes = write */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, edi + sub esi, ebp /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_contiguous_in_window: + add esi, eax + sub esi, ecx /* from += write - nbytes */ + + mov eax, [esp+64] /* eax = len */ + cmp eax, ecx + jbe L_do_copy /* if (nbytes >= len) */ + + sub eax, ecx /* len -= nbytes */ + rep movsb + mov esi, edi + sub esi, ebp /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_do_copy: + mov ecx, eax + rep movsb + + mov esi, [esp+8] /* move in back to %esi, toss from */ + mov ebp, [esp+32] /* ebp = lcode */ + jmp L_while_test + +L_test_for_end_of_block: + test al, 32 + jz L_invalid_literal_length_code + mov dword ptr [esp+72], 1 + jmp L_break_loop_with_status + +L_invalid_literal_length_code: + mov dword ptr [esp+72], 2 + jmp L_break_loop_with_status + +L_invalid_distance_code: + mov dword ptr [esp+72], 3 + jmp L_break_loop_with_status + +L_invalid_distance_too_far: + mov esi, [esp+4] + mov dword ptr [esp+72], 4 + jmp L_break_loop_with_status + +L_break_loop: + mov dword ptr [esp+72], 0 + +L_break_loop_with_status: +/* put in, out, bits, and hold back into ar and pop esp */ + mov [esp+8], esi /* save in */ + mov [esp+16], edi /* save out */ + mov [esp+44], ebx /* save bits */ + mov [esp+40], edx /* save hold */ + mov ebp, [esp+4] /* restore esp, ebp */ + mov esp, [esp] + } +#else +#error "x86 architecture not defined" +#endif + + if (ar.status > 1) { + if (ar.status == 2) + strm->msg = "invalid literal/length code"; + else if (ar.status == 3) + strm->msg = "invalid distance code"; + else + strm->msg = "invalid distance too far back"; + state->mode = BAD; + } + else if ( ar.status == 1 ) { + state->mode = TYPE; + } + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + ar.len = ar.bits >> 3; + ar.in -= ar.len; + ar.bits -= ar.len << 3; + ar.hold &= (1U << ar.bits) - 1; + + /* update state and return */ + strm->next_in = ar.in; + strm->next_out = ar.out; + strm->avail_in = (unsigned)(ar.in < ar.last ? + PAD_AVAIL_IN + (ar.last - ar.in) : + PAD_AVAIL_IN - (ar.in - ar.last)); + strm->avail_out = (unsigned)(ar.out < ar.end ? + PAD_AVAIL_OUT + (ar.end - ar.out) : + PAD_AVAIL_OUT - (ar.out - ar.end)); + state->hold = ar.hold; + state->bits = ar.bits; + return; +} + diff --git a/libz/contrib/inflate86/inffast.S b/libz/contrib/inflate86/inffast.S new file mode 100644 index 000000000..2245a2905 --- /dev/null +++ b/libz/contrib/inflate86/inffast.S @@ -0,0 +1,1368 @@ +/* + * inffast.S is a hand tuned assembler version of: + * + * inffast.c -- fast decoding + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * This version (Jan-23-2003) of inflate_fast was coded and tested under + * GNU/Linux on a pentium 3, using the gcc-3.2 compiler distribution. On that + * machine, I found that gzip style archives decompressed about 20% faster than + * the gcc-3.2 -O3 -fomit-frame-pointer compiled version. Your results will + * depend on how large of a buffer is used for z_stream.next_in & next_out + * (8K-32K worked best for my 256K cpu cache) and how much overhead there is in + * stream processing I/O and crc32/addler32. In my case, this routine used + * 70% of the cpu time and crc32 used 20%. + * + * I am confident that this version will work in the general case, but I have + * not tested a wide variety of datasets or a wide variety of platforms. + * + * Jan-24-2003 -- Added -DUSE_MMX define for slightly faster inflating. + * It should be a runtime flag instead of compile time flag... + * + * Jan-26-2003 -- Added runtime check for MMX support with cpuid instruction. + * With -DUSE_MMX, only MMX code is compiled. With -DNO_MMX, only non-MMX code + * is compiled. Without either option, runtime detection is enabled. Runtime + * detection should work on all modern cpus and the recomended algorithm (flip + * ID bit on eflags and then use the cpuid instruction) is used in many + * multimedia applications. Tested under win2k with gcc-2.95 and gas-2.12 + * distributed with cygwin3. Compiling with gcc-2.95 -c inffast.S -o + * inffast.obj generates a COFF object which can then be linked with MSVC++ + * compiled code. Tested under FreeBSD 4.7 with gcc-2.95. + * + * Jan-28-2003 -- Tested Athlon XP... MMX mode is slower than no MMX (and + * slower than compiler generated code). Adjusted cpuid check to use the MMX + * code only for Pentiums < P4 until I have more data on the P4. Speed + * improvment is only about 15% on the Athlon when compared with code generated + * with MSVC++. Not sure yet, but I think the P4 will also be slower using the + * MMX mode because many of it's x86 ALU instructions execute in .5 cycles and + * have less latency than MMX ops. Added code to buffer the last 11 bytes of + * the input stream since the MMX code grabs bits in chunks of 32, which + * differs from the inffast.c algorithm. I don't think there would have been + * read overruns where a page boundary was crossed (a segfault), but there + * could have been overruns when next_in ends on unaligned memory (unintialized + * memory read). + * + * Mar-13-2003 -- P4 MMX is slightly slower than P4 NO_MMX. I created a C + * version of the non-MMX code so that it doesn't depend on zstrm and zstate + * structure offsets which are hard coded in this file. This was last tested + * with zlib-1.2.0 which is currently in beta testing, newer versions of this + * and inffas86.c can be found at http://www.eetbeetee.com/zlib/ and + * http://www.charm.net/~christop/zlib/ + */ + + +/* + * if you have underscore linking problems (_inflate_fast undefined), try + * using -DGAS_COFF + */ +#if ! defined( GAS_COFF ) && ! defined( GAS_ELF ) + +#if defined( WIN32 ) || defined( __CYGWIN__ ) +#define GAS_COFF /* windows object format */ +#else +#define GAS_ELF +#endif + +#endif /* ! GAS_COFF && ! GAS_ELF */ + + +#if defined( GAS_COFF ) + +/* coff externals have underscores */ +#define inflate_fast _inflate_fast +#define inflate_fast_use_mmx _inflate_fast_use_mmx + +#endif /* GAS_COFF */ + + +.file "inffast.S" + +.globl inflate_fast + +.text +.align 4,0 +.L_invalid_literal_length_code_msg: +.string "invalid literal/length code" + +.align 4,0 +.L_invalid_distance_code_msg: +.string "invalid distance code" + +.align 4,0 +.L_invalid_distance_too_far_msg: +.string "invalid distance too far back" + +#if ! defined( NO_MMX ) +.align 4,0 +.L_mask: /* mask[N] = ( 1 << N ) - 1 */ +.long 0 +.long 1 +.long 3 +.long 7 +.long 15 +.long 31 +.long 63 +.long 127 +.long 255 +.long 511 +.long 1023 +.long 2047 +.long 4095 +.long 8191 +.long 16383 +.long 32767 +.long 65535 +.long 131071 +.long 262143 +.long 524287 +.long 1048575 +.long 2097151 +.long 4194303 +.long 8388607 +.long 16777215 +.long 33554431 +.long 67108863 +.long 134217727 +.long 268435455 +.long 536870911 +.long 1073741823 +.long 2147483647 +.long 4294967295 +#endif /* NO_MMX */ + +.text + +/* + * struct z_stream offsets, in zlib.h + */ +#define next_in_strm 0 /* strm->next_in */ +#define avail_in_strm 4 /* strm->avail_in */ +#define next_out_strm 12 /* strm->next_out */ +#define avail_out_strm 16 /* strm->avail_out */ +#define msg_strm 24 /* strm->msg */ +#define state_strm 28 /* strm->state */ + +/* + * struct inflate_state offsets, in inflate.h + */ +#define mode_state 0 /* state->mode */ +#define wsize_state 32 /* state->wsize */ +#define write_state 40 /* state->write */ +#define window_state 44 /* state->window */ +#define hold_state 48 /* state->hold */ +#define bits_state 52 /* state->bits */ +#define lencode_state 68 /* state->lencode */ +#define distcode_state 72 /* state->distcode */ +#define lenbits_state 76 /* state->lenbits */ +#define distbits_state 80 /* state->distbits */ + +/* + * inflate_fast's activation record + */ +#define local_var_size 64 /* how much local space for vars */ +#define strm_sp 88 /* first arg: z_stream * (local_var_size + 24) */ +#define start_sp 92 /* second arg: unsigned int (local_var_size + 28) */ + +/* + * offsets for local vars on stack + */ +#define out 60 /* unsigned char* */ +#define window 56 /* unsigned char* */ +#define wsize 52 /* unsigned int */ +#define write 48 /* unsigned int */ +#define in 44 /* unsigned char* */ +#define beg 40 /* unsigned char* */ +#define buf 28 /* char[ 12 ] */ +#define len 24 /* unsigned int */ +#define last 20 /* unsigned char* */ +#define end 16 /* unsigned char* */ +#define dcode 12 /* code* */ +#define lcode 8 /* code* */ +#define dmask 4 /* unsigned int */ +#define lmask 0 /* unsigned int */ + +/* + * typedef enum inflate_mode consts, in inflate.h + */ +#define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */ +#define INFLATE_MODE_BAD 26 + + +#if ! defined( USE_MMX ) && ! defined( NO_MMX ) + +#define RUN_TIME_MMX + +#define CHECK_MMX 1 +#define DO_USE_MMX 2 +#define DONT_USE_MMX 3 + +.globl inflate_fast_use_mmx + +.data + +.align 4,0 +inflate_fast_use_mmx: /* integer flag for run time control 1=check,2=mmx,3=no */ +.long CHECK_MMX + +#if defined( GAS_ELF ) +/* elf info */ +.type inflate_fast_use_mmx,@object +.size inflate_fast_use_mmx,4 +#endif + +#endif /* RUN_TIME_MMX */ + +#if defined( GAS_COFF ) +/* coff info: scl 2 = extern, type 32 = function */ +.def inflate_fast; .scl 2; .type 32; .endef +#endif + +.text + +.align 32,0x90 +inflate_fast: + pushl %edi + pushl %esi + pushl %ebp + pushl %ebx + pushf /* save eflags (strm_sp, state_sp assumes this is 32 bits) */ + subl $local_var_size, %esp + cld + +#define strm_r %esi +#define state_r %edi + + movl strm_sp(%esp), strm_r + movl state_strm(strm_r), state_r + + /* in = strm->next_in; + * out = strm->next_out; + * last = in + strm->avail_in - 11; + * beg = out - (start - strm->avail_out); + * end = out + (strm->avail_out - 257); + */ + movl avail_in_strm(strm_r), %edx + movl next_in_strm(strm_r), %eax + + addl %eax, %edx /* avail_in += next_in */ + subl $11, %edx /* avail_in -= 11 */ + + movl %eax, in(%esp) + movl %edx, last(%esp) + + movl start_sp(%esp), %ebp + movl avail_out_strm(strm_r), %ecx + movl next_out_strm(strm_r), %ebx + + subl %ecx, %ebp /* start -= avail_out */ + negl %ebp /* start = -start */ + addl %ebx, %ebp /* start += next_out */ + + subl $257, %ecx /* avail_out -= 257 */ + addl %ebx, %ecx /* avail_out += out */ + + movl %ebx, out(%esp) + movl %ebp, beg(%esp) + movl %ecx, end(%esp) + + /* wsize = state->wsize; + * write = state->write; + * window = state->window; + * hold = state->hold; + * bits = state->bits; + * lcode = state->lencode; + * dcode = state->distcode; + * lmask = ( 1 << state->lenbits ) - 1; + * dmask = ( 1 << state->distbits ) - 1; + */ + + movl lencode_state(state_r), %eax + movl distcode_state(state_r), %ecx + + movl %eax, lcode(%esp) + movl %ecx, dcode(%esp) + + movl $1, %eax + movl lenbits_state(state_r), %ecx + shll %cl, %eax + decl %eax + movl %eax, lmask(%esp) + + movl $1, %eax + movl distbits_state(state_r), %ecx + shll %cl, %eax + decl %eax + movl %eax, dmask(%esp) + + movl wsize_state(state_r), %eax + movl write_state(state_r), %ecx + movl window_state(state_r), %edx + + movl %eax, wsize(%esp) + movl %ecx, write(%esp) + movl %edx, window(%esp) + + movl hold_state(state_r), %ebp + movl bits_state(state_r), %ebx + +#undef strm_r +#undef state_r + +#define in_r %esi +#define from_r %esi +#define out_r %edi + + movl in(%esp), in_r + movl last(%esp), %ecx + cmpl in_r, %ecx + ja .L_align_long /* if in < last */ + + addl $11, %ecx /* ecx = &in[ avail_in ] */ + subl in_r, %ecx /* ecx = avail_in */ + movl $12, %eax + subl %ecx, %eax /* eax = 12 - avail_in */ + leal buf(%esp), %edi + rep movsb /* memcpy( buf, in, avail_in ) */ + movl %eax, %ecx + xorl %eax, %eax + rep stosb /* memset( &buf[ avail_in ], 0, 12 - avail_in ) */ + leal buf(%esp), in_r /* in = buf */ + movl in_r, last(%esp) /* last = in, do just one iteration */ + jmp .L_is_aligned + + /* align in_r on long boundary */ +.L_align_long: + testl $3, in_r + jz .L_is_aligned + xorl %eax, %eax + movb (in_r), %al + incl in_r + movl %ebx, %ecx + addl $8, %ebx + shll %cl, %eax + orl %eax, %ebp + jmp .L_align_long + +.L_is_aligned: + movl out(%esp), out_r + +#if defined( NO_MMX ) + jmp .L_do_loop +#endif + +#if defined( USE_MMX ) + jmp .L_init_mmx +#endif + +/*** Runtime MMX check ***/ + +#if defined( RUN_TIME_MMX ) +.L_check_mmx: + cmpl $DO_USE_MMX, inflate_fast_use_mmx + je .L_init_mmx + ja .L_do_loop /* > 2 */ + + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + pushf + movl (%esp), %eax /* copy eflags to eax */ + xorl $0x200000, (%esp) /* try toggling ID bit of eflags (bit 21) + * to see if cpu supports cpuid... + * ID bit method not supported by NexGen but + * bios may load a cpuid instruction and + * cpuid may be disabled on Cyrix 5-6x86 */ + popf + pushf + popl %edx /* copy new eflags to edx */ + xorl %eax, %edx /* test if ID bit is flipped */ + jz .L_dont_use_mmx /* not flipped if zero */ + xorl %eax, %eax + cpuid + cmpl $0x756e6547, %ebx /* check for GenuineIntel in ebx,ecx,edx */ + jne .L_dont_use_mmx + cmpl $0x6c65746e, %ecx + jne .L_dont_use_mmx + cmpl $0x49656e69, %edx + jne .L_dont_use_mmx + movl $1, %eax + cpuid /* get cpu features */ + shrl $8, %eax + andl $15, %eax + cmpl $6, %eax /* check for Pentium family, is 0xf for P4 */ + jne .L_dont_use_mmx + testl $0x800000, %edx /* test if MMX feature is set (bit 23) */ + jnz .L_use_mmx + jmp .L_dont_use_mmx +.L_use_mmx: + movl $DO_USE_MMX, inflate_fast_use_mmx + jmp .L_check_mmx_pop +.L_dont_use_mmx: + movl $DONT_USE_MMX, inflate_fast_use_mmx +.L_check_mmx_pop: + popl %edx + popl %ecx + popl %ebx + popl %eax + jmp .L_check_mmx +#endif + + +/*** Non-MMX code ***/ + +#if defined ( NO_MMX ) || defined( RUN_TIME_MMX ) + +#define hold_r %ebp +#define bits_r %bl +#define bitslong_r %ebx + +.align 32,0x90 +.L_while_test: + /* while (in < last && out < end) + */ + cmpl out_r, end(%esp) + jbe .L_break_loop /* if (out >= end) */ + + cmpl in_r, last(%esp) + jbe .L_break_loop + +.L_do_loop: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out + * + * do { + * if (bits < 15) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * this = lcode[hold & lmask] + */ + cmpb $15, bits_r + ja .L_get_length_code /* if (15 < bits) */ + + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + +.L_get_length_code: + movl lmask(%esp), %edx /* edx = lmask */ + movl lcode(%esp), %ecx /* ecx = lcode */ + andl hold_r, %edx /* edx &= hold */ + movl (%ecx,%edx,4), %eax /* eax = lcode[hold & lmask] */ + +.L_dolen: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out + * + * dolen: + * bits -= this.bits; + * hold >>= this.bits + */ + movb %ah, %cl /* cl = this.bits */ + subb %ah, bits_r /* bits -= this.bits */ + shrl %cl, hold_r /* hold >>= this.bits */ + + /* check if op is a literal + * if (op == 0) { + * PUP(out) = this.val; + * } + */ + testb %al, %al + jnz .L_test_for_length_base /* if (op != 0) 45.7% */ + + shrl $16, %eax /* output this.val char */ + stosb + jmp .L_while_test + +.L_test_for_length_base: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len + * + * else if (op & 16) { + * len = this.val + * op &= 15 + * if (op) { + * if (op > bits) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * len += hold & mask[op]; + * bits -= op; + * hold >>= op; + * } + */ +#define len_r %edx + movl %eax, len_r /* len = this */ + shrl $16, len_r /* len = this.val */ + movb %al, %cl + + testb $16, %al + jz .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */ + andb $15, %cl /* op &= 15 */ + jz .L_save_len /* if (!op) */ + cmpb %cl, bits_r + jae .L_add_bits_to_len /* if (op <= bits) */ + + movb %cl, %ch /* stash op in ch, freeing cl */ + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + movb %ch, %cl /* move op back to ecx */ + +.L_add_bits_to_len: + movl $1, %eax + shll %cl, %eax + decl %eax + subb %cl, bits_r + andl hold_r, %eax /* eax &= hold */ + shrl %cl, hold_r + addl %eax, len_r /* len += hold & mask[op] */ + +.L_save_len: + movl len_r, len(%esp) /* save len */ +#undef len_r + +.L_decode_distance: + /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * + * if (bits < 15) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * this = dcode[hold & dmask]; + * dodist: + * bits -= this.bits; + * hold >>= this.bits; + * op = this.op; + */ + + cmpb $15, bits_r + ja .L_get_distance_code /* if (15 < bits) */ + + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + +.L_get_distance_code: + movl dmask(%esp), %edx /* edx = dmask */ + movl dcode(%esp), %ecx /* ecx = dcode */ + andl hold_r, %edx /* edx &= hold */ + movl (%ecx,%edx,4), %eax /* eax = dcode[hold & dmask] */ + +#define dist_r %edx +.L_dodist: + movl %eax, dist_r /* dist = this */ + shrl $16, dist_r /* dist = this.val */ + movb %ah, %cl + subb %ah, bits_r /* bits -= this.bits */ + shrl %cl, hold_r /* hold >>= this.bits */ + + /* if (op & 16) { + * dist = this.val + * op &= 15 + * if (op > bits) { + * hold |= *((unsigned short *)in)++ << bits; + * bits += 16 + * } + * dist += hold & mask[op]; + * bits -= op; + * hold >>= op; + */ + movb %al, %cl /* cl = this.op */ + + testb $16, %al /* if ((op & 16) == 0) */ + jz .L_test_for_second_level_dist + andb $15, %cl /* op &= 15 */ + jz .L_check_dist_one + cmpb %cl, bits_r + jae .L_add_bits_to_dist /* if (op <= bits) 97.6% */ + + movb %cl, %ch /* stash op in ch, freeing cl */ + xorl %eax, %eax + lodsw /* al = *(ushort *)in++ */ + movb bits_r, %cl /* cl = bits, needs it for shifting */ + addb $16, bits_r /* bits += 16 */ + shll %cl, %eax + orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */ + movb %ch, %cl /* move op back to ecx */ + +.L_add_bits_to_dist: + movl $1, %eax + shll %cl, %eax + decl %eax /* (1 << op) - 1 */ + subb %cl, bits_r + andl hold_r, %eax /* eax &= hold */ + shrl %cl, hold_r + addl %eax, dist_r /* dist += hold & ((1 << op) - 1) */ + jmp .L_check_window + +.L_check_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes + * + * nbytes = out - beg; + * if (dist <= nbytes) { + * from = out - dist; + * do { + * PUP(out) = PUP(from); + * } while (--len > 0) { + * } + */ + + movl in_r, in(%esp) /* save in so from can use it's reg */ + movl out_r, %eax + subl beg(%esp), %eax /* nbytes = out - beg */ + + cmpl dist_r, %eax + jb .L_clip_window /* if (dist > nbytes) 4.2% */ + + movl len(%esp), %ecx + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + + subl $3, %ecx + movb (from_r), %al + movb %al, (out_r) + movb 1(from_r), %al + movb 2(from_r), %dl + addl $3, from_r + movb %al, 1(out_r) + movb %dl, 2(out_r) + addl $3, out_r + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + jmp .L_while_test + +.align 16,0x90 +.L_check_dist_one: + cmpl $1, dist_r + jne .L_check_window + cmpl out_r, beg(%esp) + je .L_check_window + + decl out_r + movl len(%esp), %ecx + movb (out_r), %al + subl $3, %ecx + + movb %al, 1(out_r) + movb %al, 2(out_r) + movb %al, 3(out_r) + addl $4, out_r + rep stosb + + jmp .L_while_test + +.align 16,0x90 +.L_test_for_second_level_length: + /* else if ((op & 64) == 0) { + * this = lcode[this.val + (hold & mask[op])]; + * } + */ + testb $64, %al + jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */ + + movl $1, %eax + shll %cl, %eax + decl %eax + andl hold_r, %eax /* eax &= hold */ + addl %edx, %eax /* eax += this.val */ + movl lcode(%esp), %edx /* edx = lcode */ + movl (%edx,%eax,4), %eax /* eax = lcode[val + (hold&mask[op])] */ + jmp .L_dolen + +.align 16,0x90 +.L_test_for_second_level_dist: + /* else if ((op & 64) == 0) { + * this = dcode[this.val + (hold & mask[op])]; + * } + */ + testb $64, %al + jnz .L_invalid_distance_code /* if ((op & 64) != 0) */ + + movl $1, %eax + shll %cl, %eax + decl %eax + andl hold_r, %eax /* eax &= hold */ + addl %edx, %eax /* eax += this.val */ + movl dcode(%esp), %edx /* edx = dcode */ + movl (%edx,%eax,4), %eax /* eax = dcode[val + (hold&mask[op])] */ + jmp .L_dodist + +.align 16,0x90 +.L_clip_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes + * + * else { + * if (dist > wsize) { + * invalid distance + * } + * from = window; + * nbytes = dist - nbytes; + * if (write == 0) { + * from += wsize - nbytes; + */ +#define nbytes_r %ecx + movl %eax, nbytes_r + movl wsize(%esp), %eax /* prepare for dist compare */ + negl nbytes_r /* nbytes = -nbytes */ + movl window(%esp), from_r /* from = window */ + + cmpl dist_r, %eax + jb .L_invalid_distance_too_far /* if (dist > wsize) */ + + addl dist_r, nbytes_r /* nbytes = dist - nbytes */ + cmpl $0, write(%esp) + jne .L_wrap_around_window /* if (write != 0) */ + + subl nbytes_r, %eax + addl %eax, from_r /* from += wsize - nbytes */ + + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes, %eax = len + * + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while (--nbytes); + * from = out - dist; + * } + * } + */ +#define len_r %eax + movl len(%esp), len_r + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1 + + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1 + +.L_wrap_around_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes, %eax = write, %eax = len + * + * else if (write < nbytes) { + * from += wsize + write - nbytes; + * nbytes -= write; + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while (--nbytes); + * from = window; + * nbytes = write; + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while(--nbytes); + * from = out - dist; + * } + * } + * } + */ +#define write_r %eax + movl write(%esp), write_r + cmpl write_r, nbytes_r + jbe .L_contiguous_in_window /* if (write >= nbytes) */ + + addl wsize(%esp), from_r + addl write_r, from_r + subl nbytes_r, from_r /* from += wsize + write - nbytes */ + subl write_r, nbytes_r /* nbytes -= write */ +#undef write_r + + movl len(%esp), len_r + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl window(%esp), from_r /* from = window */ + movl write(%esp), nbytes_r /* nbytes = write */ + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1 + +.L_contiguous_in_window: + /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist + * %ecx = nbytes, %eax = write, %eax = len + * + * else { + * from += write - nbytes; + * if (nbytes < len) { + * len -= nbytes; + * do { + * PUP(out) = PUP(from); + * } while (--nbytes); + * from = out - dist; + * } + * } + */ +#define write_r %eax + addl write_r, from_r + subl nbytes_r, from_r /* from += write - nbytes */ +#undef write_r + + movl len(%esp), len_r + cmpl nbytes_r, len_r + jbe .L_do_copy1 /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + +.L_do_copy1: + /* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out + * %eax = len + * + * while (len > 0) { + * PUP(out) = PUP(from); + * len--; + * } + * } + * } while (in < last && out < end); + */ +#undef nbytes_r +#define in_r %esi + movl len_r, %ecx + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + jmp .L_while_test + +#undef len_r +#undef dist_r + +#endif /* NO_MMX || RUN_TIME_MMX */ + + +/*** MMX code ***/ + +#if defined( USE_MMX ) || defined( RUN_TIME_MMX ) + +.align 32,0x90 +.L_init_mmx: + emms + +#undef bits_r +#undef bitslong_r +#define bitslong_r %ebp +#define hold_mm %mm0 + movd %ebp, hold_mm + movl %ebx, bitslong_r + +#define used_mm %mm1 +#define dmask2_mm %mm2 +#define lmask2_mm %mm3 +#define lmask_mm %mm4 +#define dmask_mm %mm5 +#define tmp_mm %mm6 + + movd lmask(%esp), lmask_mm + movq lmask_mm, lmask2_mm + movd dmask(%esp), dmask_mm + movq dmask_mm, dmask2_mm + pxor used_mm, used_mm + movl lcode(%esp), %ebx /* ebx = lcode */ + jmp .L_do_loop_mmx + +.align 32,0x90 +.L_while_test_mmx: + /* while (in < last && out < end) + */ + cmpl out_r, end(%esp) + jbe .L_break_loop /* if (out >= end) */ + + cmpl in_r, last(%esp) + jbe .L_break_loop + +.L_do_loop_mmx: + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + + cmpl $32, bitslong_r + ja .L_get_length_code_mmx /* if (32 < bits) */ + + movd bitslong_r, tmp_mm + movd (in_r), %mm7 + addl $4, in_r + psllq tmp_mm, %mm7 + addl $32, bitslong_r + por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */ + +.L_get_length_code_mmx: + pand hold_mm, lmask_mm + movd lmask_mm, %eax + movq lmask2_mm, lmask_mm + movl (%ebx,%eax,4), %eax /* eax = lcode[hold & lmask] */ + +.L_dolen_mmx: + movzbl %ah, %ecx /* ecx = this.bits */ + movd %ecx, used_mm + subl %ecx, bitslong_r /* bits -= this.bits */ + + testb %al, %al + jnz .L_test_for_length_base_mmx /* if (op != 0) 45.7% */ + + shrl $16, %eax /* output this.val char */ + stosb + jmp .L_while_test_mmx + +.L_test_for_length_base_mmx: +#define len_r %edx + movl %eax, len_r /* len = this */ + shrl $16, len_r /* len = this.val */ + + testb $16, %al + jz .L_test_for_second_level_length_mmx /* if ((op & 16) == 0) 8% */ + andl $15, %eax /* op &= 15 */ + jz .L_decode_distance_mmx /* if (!op) */ + + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd %eax, used_mm + movd hold_mm, %ecx + subl %eax, bitslong_r + andl .L_mask(,%eax,4), %ecx + addl %ecx, len_r /* len += hold & mask[op] */ + +.L_decode_distance_mmx: + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + + cmpl $32, bitslong_r + ja .L_get_dist_code_mmx /* if (32 < bits) */ + + movd bitslong_r, tmp_mm + movd (in_r), %mm7 + addl $4, in_r + psllq tmp_mm, %mm7 + addl $32, bitslong_r + por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */ + +.L_get_dist_code_mmx: + movl dcode(%esp), %ebx /* ebx = dcode */ + pand hold_mm, dmask_mm + movd dmask_mm, %eax + movq dmask2_mm, dmask_mm + movl (%ebx,%eax,4), %eax /* eax = dcode[hold & lmask] */ + +.L_dodist_mmx: +#define dist_r %ebx + movzbl %ah, %ecx /* ecx = this.bits */ + movl %eax, dist_r + shrl $16, dist_r /* dist = this.val */ + subl %ecx, bitslong_r /* bits -= this.bits */ + movd %ecx, used_mm + + testb $16, %al /* if ((op & 16) == 0) */ + jz .L_test_for_second_level_dist_mmx + andl $15, %eax /* op &= 15 */ + jz .L_check_dist_one_mmx + +.L_add_bits_to_dist_mmx: + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd %eax, used_mm /* save bit length of current op */ + movd hold_mm, %ecx /* get the next bits on input stream */ + subl %eax, bitslong_r /* bits -= op bits */ + andl .L_mask(,%eax,4), %ecx /* ecx = hold & mask[op] */ + addl %ecx, dist_r /* dist += hold & mask[op] */ + +.L_check_window_mmx: + movl in_r, in(%esp) /* save in so from can use it's reg */ + movl out_r, %eax + subl beg(%esp), %eax /* nbytes = out - beg */ + + cmpl dist_r, %eax + jb .L_clip_window_mmx /* if (dist > nbytes) 4.2% */ + + movl len_r, %ecx + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + + subl $3, %ecx + movb (from_r), %al + movb %al, (out_r) + movb 1(from_r), %al + movb 2(from_r), %dl + addl $3, from_r + movb %al, 1(out_r) + movb %dl, 2(out_r) + addl $3, out_r + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */ + jmp .L_while_test_mmx + +.align 16,0x90 +.L_check_dist_one_mmx: + cmpl $1, dist_r + jne .L_check_window_mmx + cmpl out_r, beg(%esp) + je .L_check_window_mmx + + decl out_r + movl len_r, %ecx + movb (out_r), %al + subl $3, %ecx + + movb %al, 1(out_r) + movb %al, 2(out_r) + movb %al, 3(out_r) + addl $4, out_r + rep stosb + + movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */ + jmp .L_while_test_mmx + +.align 16,0x90 +.L_test_for_second_level_length_mmx: + testb $64, %al + jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */ + + andl $15, %eax + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd hold_mm, %ecx + andl .L_mask(,%eax,4), %ecx + addl len_r, %ecx + movl (%ebx,%ecx,4), %eax /* eax = lcode[hold & lmask] */ + jmp .L_dolen_mmx + +.align 16,0x90 +.L_test_for_second_level_dist_mmx: + testb $64, %al + jnz .L_invalid_distance_code /* if ((op & 64) != 0) */ + + andl $15, %eax + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd hold_mm, %ecx + andl .L_mask(,%eax,4), %ecx + movl dcode(%esp), %eax /* ecx = dcode */ + addl dist_r, %ecx + movl (%eax,%ecx,4), %eax /* eax = lcode[hold & lmask] */ + jmp .L_dodist_mmx + +.align 16,0x90 +.L_clip_window_mmx: +#define nbytes_r %ecx + movl %eax, nbytes_r + movl wsize(%esp), %eax /* prepare for dist compare */ + negl nbytes_r /* nbytes = -nbytes */ + movl window(%esp), from_r /* from = window */ + + cmpl dist_r, %eax + jb .L_invalid_distance_too_far /* if (dist > wsize) */ + + addl dist_r, nbytes_r /* nbytes = dist - nbytes */ + cmpl $0, write(%esp) + jne .L_wrap_around_window_mmx /* if (write != 0) */ + + subl nbytes_r, %eax + addl %eax, from_r /* from += wsize - nbytes */ + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1_mmx + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1_mmx + +.L_wrap_around_window_mmx: +#define write_r %eax + movl write(%esp), write_r + cmpl write_r, nbytes_r + jbe .L_contiguous_in_window_mmx /* if (write >= nbytes) */ + + addl wsize(%esp), from_r + addl write_r, from_r + subl nbytes_r, from_r /* from += wsize + write - nbytes */ + subl write_r, nbytes_r /* nbytes -= write */ +#undef write_r + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl window(%esp), from_r /* from = window */ + movl write(%esp), nbytes_r /* nbytes = write */ + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + jmp .L_do_copy1_mmx + +.L_contiguous_in_window_mmx: +#define write_r %eax + addl write_r, from_r + subl nbytes_r, from_r /* from += write - nbytes */ +#undef write_r + + cmpl nbytes_r, len_r + jbe .L_do_copy1_mmx /* if (nbytes >= len) */ + + subl nbytes_r, len_r /* len -= nbytes */ + rep movsb + movl out_r, from_r + subl dist_r, from_r /* from = out - dist */ + +.L_do_copy1_mmx: +#undef nbytes_r +#define in_r %esi + movl len_r, %ecx + rep movsb + + movl in(%esp), in_r /* move in back to %esi, toss from */ + movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */ + jmp .L_while_test_mmx + +#undef hold_r +#undef bitslong_r + +#endif /* USE_MMX || RUN_TIME_MMX */ + + +/*** USE_MMX, NO_MMX, and RUNTIME_MMX from here on ***/ + +.L_invalid_distance_code: + /* else { + * strm->msg = "invalid distance code"; + * state->mode = BAD; + * } + */ + movl $.L_invalid_distance_code_msg, %ecx + movl $INFLATE_MODE_BAD, %edx + jmp .L_update_stream_state + +.L_test_for_end_of_block: + /* else if (op & 32) { + * state->mode = TYPE; + * break; + * } + */ + testb $32, %al + jz .L_invalid_literal_length_code /* if ((op & 32) == 0) */ + + movl $0, %ecx + movl $INFLATE_MODE_TYPE, %edx + jmp .L_update_stream_state + +.L_invalid_literal_length_code: + /* else { + * strm->msg = "invalid literal/length code"; + * state->mode = BAD; + * } + */ + movl $.L_invalid_literal_length_code_msg, %ecx + movl $INFLATE_MODE_BAD, %edx + jmp .L_update_stream_state + +.L_invalid_distance_too_far: + /* strm->msg = "invalid distance too far back"; + * state->mode = BAD; + */ + movl in(%esp), in_r /* from_r has in's reg, put in back */ + movl $.L_invalid_distance_too_far_msg, %ecx + movl $INFLATE_MODE_BAD, %edx + jmp .L_update_stream_state + +.L_update_stream_state: + /* set strm->msg = %ecx, strm->state->mode = %edx */ + movl strm_sp(%esp), %eax + testl %ecx, %ecx /* if (msg != NULL) */ + jz .L_skip_msg + movl %ecx, msg_strm(%eax) /* strm->msg = msg */ +.L_skip_msg: + movl state_strm(%eax), %eax /* state = strm->state */ + movl %edx, mode_state(%eax) /* state->mode = edx (BAD | TYPE) */ + jmp .L_break_loop + +.align 32,0x90 +.L_break_loop: + +/* + * Regs: + * + * bits = %ebp when mmx, and in %ebx when non-mmx + * hold = %hold_mm when mmx, and in %ebp when non-mmx + * in = %esi + * out = %edi + */ + +#if defined( USE_MMX ) || defined( RUN_TIME_MMX ) + +#if defined( RUN_TIME_MMX ) + + cmpl $DO_USE_MMX, inflate_fast_use_mmx + jne .L_update_next_in + +#endif /* RUN_TIME_MMX */ + + movl %ebp, %ebx + +.L_update_next_in: + +#endif + +#define strm_r %eax +#define state_r %edx + + /* len = bits >> 3; + * in -= len; + * bits -= len << 3; + * hold &= (1U << bits) - 1; + * state->hold = hold; + * state->bits = bits; + * strm->next_in = in; + * strm->next_out = out; + */ + movl strm_sp(%esp), strm_r + movl %ebx, %ecx + movl state_strm(strm_r), state_r + shrl $3, %ecx + subl %ecx, in_r + shll $3, %ecx + subl %ecx, %ebx + movl out_r, next_out_strm(strm_r) + movl %ebx, bits_state(state_r) + movl %ebx, %ecx + + leal buf(%esp), %ebx + cmpl %ebx, last(%esp) + jne .L_buf_not_used /* if buf != last */ + + subl %ebx, in_r /* in -= buf */ + movl next_in_strm(strm_r), %ebx + movl %ebx, last(%esp) /* last = strm->next_in */ + addl %ebx, in_r /* in += strm->next_in */ + movl avail_in_strm(strm_r), %ebx + subl $11, %ebx + addl %ebx, last(%esp) /* last = &strm->next_in[ avail_in - 11 ] */ + +.L_buf_not_used: + movl in_r, next_in_strm(strm_r) + + movl $1, %ebx + shll %cl, %ebx + decl %ebx + +#if defined( USE_MMX ) || defined( RUN_TIME_MMX ) + +#if defined( RUN_TIME_MMX ) + + cmpl $DO_USE_MMX, inflate_fast_use_mmx + jne .L_update_hold + +#endif /* RUN_TIME_MMX */ + + psrlq used_mm, hold_mm /* hold_mm >>= last bit length */ + movd hold_mm, %ebp + + emms + +.L_update_hold: + +#endif /* USE_MMX || RUN_TIME_MMX */ + + andl %ebx, %ebp + movl %ebp, hold_state(state_r) + +#define last_r %ebx + + /* strm->avail_in = in < last ? 11 + (last - in) : 11 - (in - last) */ + movl last(%esp), last_r + cmpl in_r, last_r + jbe .L_last_is_smaller /* if (in >= last) */ + + subl in_r, last_r /* last -= in */ + addl $11, last_r /* last += 11 */ + movl last_r, avail_in_strm(strm_r) + jmp .L_fixup_out +.L_last_is_smaller: + subl last_r, in_r /* in -= last */ + negl in_r /* in = -in */ + addl $11, in_r /* in += 11 */ + movl in_r, avail_in_strm(strm_r) + +#undef last_r +#define end_r %ebx + +.L_fixup_out: + /* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/ + movl end(%esp), end_r + cmpl out_r, end_r + jbe .L_end_is_smaller /* if (out >= end) */ + + subl out_r, end_r /* end -= out */ + addl $257, end_r /* end += 257 */ + movl end_r, avail_out_strm(strm_r) + jmp .L_done +.L_end_is_smaller: + subl end_r, out_r /* out -= end */ + negl out_r /* out = -out */ + addl $257, out_r /* out += 257 */ + movl out_r, avail_out_strm(strm_r) + +#undef end_r +#undef strm_r +#undef state_r + +.L_done: + addl $local_var_size, %esp + popf + popl %ebx + popl %ebp + popl %esi + popl %edi + ret + +#if defined( GAS_ELF ) +/* elf info */ +.type inflate_fast,@function +.size inflate_fast,.-inflate_fast +#endif diff --git a/libz/contrib/iostream/test.cpp b/libz/contrib/iostream/test.cpp new file mode 100644 index 000000000..7d265b3b5 --- /dev/null +++ b/libz/contrib/iostream/test.cpp @@ -0,0 +1,24 @@ + +#include "zfstream.h" + +int main() { + + // Construct a stream object with this filebuffer. Anything sent + // to this stream will go to standard out. + gzofstream os( 1, ios::out ); + + // This text is getting compressed and sent to stdout. + // To prove this, run 'test | zcat'. + os << "Hello, Mommy" << endl; + + os << setcompressionlevel( Z_NO_COMPRESSION ); + os << "hello, hello, hi, ho!" << endl; + + setcompressionlevel( os, Z_DEFAULT_COMPRESSION ) + << "I'm compressing again" << endl; + + os.close(); + + return 0; + +} diff --git a/libz/contrib/iostream/zfstream.cpp b/libz/contrib/iostream/zfstream.cpp new file mode 100644 index 000000000..d0cd85faa --- /dev/null +++ b/libz/contrib/iostream/zfstream.cpp @@ -0,0 +1,329 @@ + +#include "zfstream.h" + +gzfilebuf::gzfilebuf() : + file(NULL), + mode(0), + own_file_descriptor(0) +{ } + +gzfilebuf::~gzfilebuf() { + + sync(); + if ( own_file_descriptor ) + close(); + +} + +gzfilebuf *gzfilebuf::open( const char *name, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + // Put the end-of-string indicator + *p = '\0'; + + if ( (file = gzopen(name, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 1; + + return this; + +} + +gzfilebuf *gzfilebuf::attach( int file_descriptor, + int io_mode ) { + + if ( is_open() ) + return NULL; + + char char_mode[10]; + char *p = char_mode; + + if ( io_mode & ios::in ) { + mode = ios::in; + *p++ = 'r'; + } else if ( io_mode & ios::app ) { + mode = ios::app; + *p++ = 'a'; + } else { + mode = ios::out; + *p++ = 'w'; + } + + if ( io_mode & ios::binary ) { + mode |= ios::binary; + *p++ = 'b'; + } + + // Hard code the compression level + if ( io_mode & (ios::out|ios::app )) { + *p++ = '9'; + } + + // Put the end-of-string indicator + *p = '\0'; + + if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) + return NULL; + + own_file_descriptor = 0; + + return this; + +} + +gzfilebuf *gzfilebuf::close() { + + if ( is_open() ) { + + sync(); + gzclose( file ); + file = NULL; + + } + + return this; + +} + +int gzfilebuf::setcompressionlevel( int comp_level ) { + + return gzsetparams(file, comp_level, -2); + +} + +int gzfilebuf::setcompressionstrategy( int comp_strategy ) { + + return gzsetparams(file, -2, comp_strategy); + +} + + +streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) { + + return streampos(EOF); + +} + +int gzfilebuf::underflow() { + + // If the file hasn't been opened for reading, error. + if ( !is_open() || !(mode & ios::in) ) + return EOF; + + // if a buffer doesn't exists, allocate one. + if ( !base() ) { + + if ( (allocate()) == EOF ) + return EOF; + setp(0,0); + + } else { + + if ( in_avail() ) + return (unsigned char) *gptr(); + + if ( out_waiting() ) { + if ( flushbuf() == EOF ) + return EOF; + } + + } + + // Attempt to fill the buffer. + + int result = fillbuf(); + if ( result == EOF ) { + // disable get area + setg(0,0,0); + return EOF; + } + + return (unsigned char) *gptr(); + +} + +int gzfilebuf::overflow( int c ) { + + if ( !is_open() || !(mode & ios::out) ) + return EOF; + + if ( !base() ) { + if ( allocate() == EOF ) + return EOF; + setg(0,0,0); + } else { + if (in_avail()) { + return EOF; + } + if (out_waiting()) { + if (flushbuf() == EOF) + return EOF; + } + } + + int bl = blen(); + setp( base(), base() + bl); + + if ( c != EOF ) { + + *pptr() = c; + pbump(1); + + } + + return 0; + +} + +int gzfilebuf::sync() { + + if ( !is_open() ) + return EOF; + + if ( out_waiting() ) + return flushbuf(); + + return 0; + +} + +int gzfilebuf::flushbuf() { + + int n; + char *q; + + q = pbase(); + n = pptr() - q; + + if ( gzwrite( file, q, n) < n ) + return EOF; + + setp(0,0); + + return 0; + +} + +int gzfilebuf::fillbuf() { + + int required; + char *p; + + p = base(); + + required = blen(); + + int t = gzread( file, p, required ); + + if ( t <= 0) return EOF; + + setg( base(), base(), base()+t); + + return t; + +} + +gzfilestream_common::gzfilestream_common() : + ios( gzfilestream_common::rdbuf() ) +{ } + +gzfilestream_common::~gzfilestream_common() +{ } + +void gzfilestream_common::attach( int fd, int io_mode ) { + + if ( !buffer.attach( fd, io_mode) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::open( const char *name, int io_mode ) { + + if ( !buffer.open( name, io_mode ) ) + clear( ios::failbit | ios::badbit ); + else + clear(); + +} + +void gzfilestream_common::close() { + + if ( !buffer.close() ) + clear( ios::failbit | ios::badbit ); + +} + +gzfilebuf *gzfilestream_common::rdbuf() +{ + return &buffer; +} + +gzifstream::gzifstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzifstream::gzifstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzifstream::gzifstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzifstream::~gzifstream() { } + +gzofstream::gzofstream() : + ios( gzfilestream_common::rdbuf() ) +{ + clear( ios::badbit ); +} + +gzofstream::gzofstream( const char *name, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::open( name, io_mode ); +} + +gzofstream::gzofstream( int fd, int io_mode ) : + ios( gzfilestream_common::rdbuf() ) +{ + gzfilestream_common::attach( fd, io_mode ); +} + +gzofstream::~gzofstream() { } diff --git a/libz/contrib/iostream/zfstream.h b/libz/contrib/iostream/zfstream.h new file mode 100644 index 000000000..ed79098a3 --- /dev/null +++ b/libz/contrib/iostream/zfstream.h @@ -0,0 +1,128 @@ + +#ifndef zfstream_h +#define zfstream_h + +#include +#include "zlib.h" + +class gzfilebuf : public streambuf { + +public: + + gzfilebuf( ); + virtual ~gzfilebuf(); + + gzfilebuf *open( const char *name, int io_mode ); + gzfilebuf *attach( int file_descriptor, int io_mode ); + gzfilebuf *close(); + + int setcompressionlevel( int comp_level ); + int setcompressionstrategy( int comp_strategy ); + + inline int is_open() const { return (file !=NULL); } + + virtual streampos seekoff( streamoff, ios::seek_dir, int ); + + virtual int sync(); + +protected: + + virtual int underflow(); + virtual int overflow( int = EOF ); + +private: + + gzFile file; + short mode; + short own_file_descriptor; + + int flushbuf(); + int fillbuf(); + +}; + +class gzfilestream_common : virtual public ios { + + friend class gzifstream; + friend class gzofstream; + friend gzofstream &setcompressionlevel( gzofstream &, int ); + friend gzofstream &setcompressionstrategy( gzofstream &, int ); + +public: + virtual ~gzfilestream_common(); + + void attach( int fd, int io_mode ); + void open( const char *name, int io_mode ); + void close(); + +protected: + gzfilestream_common(); + +private: + gzfilebuf *rdbuf(); + + gzfilebuf buffer; + +}; + +class gzifstream : public gzfilestream_common, public istream { + +public: + + gzifstream(); + gzifstream( const char *name, int io_mode = ios::in ); + gzifstream( int fd, int io_mode = ios::in ); + + virtual ~gzifstream(); + +}; + +class gzofstream : public gzfilestream_common, public ostream { + +public: + + gzofstream(); + gzofstream( const char *name, int io_mode = ios::out ); + gzofstream( int fd, int io_mode = ios::out ); + + virtual ~gzofstream(); + +}; + +template class gzomanip { + friend gzofstream &operator<<(gzofstream &, const gzomanip &); +public: + gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { } +private: + gzofstream &(*func)(gzofstream &, T); + T val; +}; + +template gzofstream &operator<<(gzofstream &s, const gzomanip &m) +{ + return (*m.func)(s, m.val); +} + +inline gzofstream &setcompressionlevel( gzofstream &s, int l ) +{ + (s.rdbuf())->setcompressionlevel(l); + return s; +} + +inline gzofstream &setcompressionstrategy( gzofstream &s, int l ) +{ + (s.rdbuf())->setcompressionstrategy(l); + return s; +} + +inline gzomanip setcompressionlevel(int l) +{ + return gzomanip(&setcompressionlevel,l); +} + +inline gzomanip setcompressionstrategy(int l) +{ + return gzomanip(&setcompressionstrategy,l); +} + +#endif diff --git a/libz/contrib/iostream2/zstream.h b/libz/contrib/iostream2/zstream.h new file mode 100644 index 000000000..43d2332b7 --- /dev/null +++ b/libz/contrib/iostream2/zstream.h @@ -0,0 +1,307 @@ +/* + * + * Copyright (c) 1997 + * Christian Michelsen Research AS + * Advanced Computing + * Fantoftvegen 38, 5036 BERGEN, Norway + * http://www.cmr.no + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Christian Michelsen Research AS makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef ZSTREAM__H +#define ZSTREAM__H + +/* + * zstream.h - C++ interface to the 'zlib' general purpose compression library + * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $ + */ + +#include +#include +#include +#include "zlib.h" + +#if defined(_WIN32) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +class zstringlen { +public: + zstringlen(class izstream&); + zstringlen(class ozstream&, const char*); + size_t value() const { return val.word; } +private: + struct Val { unsigned char byte; size_t word; } val; +}; + +// ----------------------------- izstream ----------------------------- + +class izstream +{ + public: + izstream() : m_fp(0) {} + izstream(FILE* fp) : m_fp(0) { open(fp); } + izstream(const char* name) : m_fp(0) { open(name); } + ~izstream() { close(); } + + /* Opens a gzip (.gz) file for reading. + * open() can be used to read a file which is not in gzip format; + * in this case read() will directly read from the file without + * decompression. errno can be checked to distinguish two error + * cases (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name) { + if (m_fp) close(); + m_fp = ::gzopen(name, "rb"); + } + + void open(FILE* fp) { + SET_BINARY_MODE(fp); + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), "rb"); + } + + /* Flushes all pending input if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + int r = ::gzclose(m_fp); + m_fp = 0; return r; + } + + /* Binary read the given number of bytes from the compressed file. + */ + int read(void* buf, size_t len) { + return ::gzread(m_fp, buf, len); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + private: + gzFile m_fp; +}; + +/* + * Binary read the given (array of) object(s) from the compressed file. + * If the input file was not in gzip format, read() copies the objects number + * of bytes into the buffer. + * returns the number of uncompressed bytes actually read + * (0 for end of file, -1 for error). + */ +template +inline int read(izstream& zs, T* x, Items items) { + return ::gzread(zs.fp(), x, items*sizeof(T)); +} + +/* + * Binary input with the '>' operator. + */ +template +inline izstream& operator>(izstream& zs, T& x) { + ::gzread(zs.fp(), &x, sizeof(T)); + return zs; +} + + +inline zstringlen::zstringlen(izstream& zs) { + zs > val.byte; + if (val.byte == 255) zs > val.word; + else val.word = val.byte; +} + +/* + * Read length of string + the string with the '>' operator. + */ +inline izstream& operator>(izstream& zs, char* x) { + zstringlen len(zs); + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return zs; +} + +inline char* read_string(izstream& zs) { + zstringlen len(zs); + char* x = new char[len.value()+1]; + ::gzread(zs.fp(), x, len.value()); + x[len.value()] = '\0'; + return x; +} + +// ----------------------------- ozstream ----------------------------- + +class ozstream +{ + public: + ozstream() : m_fp(0), m_os(0) { + } + ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(fp, level); + } + ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION) + : m_fp(0), m_os(0) { + open(name, level); + } + ~ozstream() { + close(); + } + + /* Opens a gzip (.gz) file for writing. + * The compression level parameter should be in 0..9 + * errno can be checked to distinguish two error cases + * (if errno is zero, the zlib error is Z_MEM_ERROR). + */ + void open(const char* name, int level = Z_DEFAULT_COMPRESSION) { + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzopen(name, mode); + } + + /* open from a FILE pointer. + */ + void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) { + SET_BINARY_MODE(fp); + char mode[4] = "wb\0"; + if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level; + if (m_fp) close(); + m_fp = ::gzdopen(fileno(fp), mode); + } + + /* Flushes all pending output if necessary, closes the compressed file + * and deallocates all the (de)compression state. The return value is + * the zlib error number (see function error() below). + */ + int close() { + if (m_os) { + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = 0; + } + int r = ::gzclose(m_fp); m_fp = 0; return r; + } + + /* Binary write the given number of bytes into the compressed file. + */ + int write(const void* buf, size_t len) { + return ::gzwrite(m_fp, (voidp) buf, len); + } + + /* Flushes all pending output into the compressed file. The parameter + * _flush is as in the deflate() function. The return value is the zlib + * error number (see function gzerror below). flush() returns Z_OK if + * the flush_ parameter is Z_FINISH and all output could be flushed. + * flush() should be called only when strictly necessary because it can + * degrade compression. + */ + int flush(int _flush) { + os_flush(); + return ::gzflush(m_fp, _flush); + } + + /* Returns the error message for the last error which occurred on the + * given compressed file. errnum is set to zlib error number. If an + * error occurred in the file system and not in the compression library, + * errnum is set to Z_ERRNO and the application may consult errno + * to get the exact error code. + */ + const char* error(int* errnum) { + return ::gzerror(m_fp, errnum); + } + + gzFile fp() { return m_fp; } + + ostream& os() { + if (m_os == 0) m_os = new ostrstream; + return *m_os; + } + + void os_flush() { + if (m_os && m_os->pcount()>0) { + ostrstream* oss = new ostrstream; + oss->fill(m_os->fill()); + oss->flags(m_os->flags()); + oss->precision(m_os->precision()); + oss->width(m_os->width()); + ::gzwrite(m_fp, m_os->str(), m_os->pcount()); + delete[] m_os->str(); delete m_os; m_os = oss; + } + } + + private: + gzFile m_fp; + ostrstream* m_os; +}; + +/* + * Binary write the given (array of) object(s) into the compressed file. + * returns the number of uncompressed bytes actually written + * (0 in case of error). + */ +template +inline int write(ozstream& zs, const T* x, Items items) { + return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T)); +} + +/* + * Binary output with the '<' operator. + */ +template +inline ozstream& operator<(ozstream& zs, const T& x) { + ::gzwrite(zs.fp(), (voidp) &x, sizeof(T)); + return zs; +} + +inline zstringlen::zstringlen(ozstream& zs, const char* x) { + val.byte = 255; val.word = ::strlen(x); + if (val.word < 255) zs < (val.byte = val.word); + else zs < val; +} + +/* + * Write length of string + the string with the '<' operator. + */ +inline ozstream& operator<(ozstream& zs, const char* x) { + zstringlen len(zs, x); + ::gzwrite(zs.fp(), (voidp) x, len.value()); + return zs; +} + +#ifdef _MSC_VER +inline ozstream& operator<(ozstream& zs, char* const& x) { + return zs < (const char*) x; +} +#endif + +/* + * Ascii write with the << operator; + */ +template +inline ostream& operator<<(ozstream& zs, const T& x) { + zs.os_flush(); + return zs.os() << x; +} + +#endif diff --git a/libz/contrib/iostream2/zstream_test.cpp b/libz/contrib/iostream2/zstream_test.cpp new file mode 100644 index 000000000..6273f62d6 --- /dev/null +++ b/libz/contrib/iostream2/zstream_test.cpp @@ -0,0 +1,25 @@ +#include "zstream.h" +#include +#include +#include + +void main() { + char h[256] = "Hello"; + char* g = "Goodbye"; + ozstream out("temp.gz"); + out < "This works well" < h < g; + out.close(); + + izstream in("temp.gz"); // read it back + char *x = read_string(in), *y = new char[256], z[256]; + in > y > z; + in.close(); + cout << x << endl << y << endl << z << endl; + + out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results + out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl; + out << z << endl << y << endl << x << endl; + out << 1.1234567890123456789 << endl; + + delete[] x; delete[] y; +} diff --git a/libz/contrib/iostream3/README b/libz/contrib/iostream3/README new file mode 100644 index 000000000..f7b319ab9 --- /dev/null +++ b/libz/contrib/iostream3/README @@ -0,0 +1,35 @@ +These classes provide a C++ stream interface to the zlib library. It allows you +to do things like: + + gzofstream outf("blah.gz"); + outf << "These go into the gzip file " << 123 << endl; + +It does this by deriving a specialized stream buffer for gzipped files, which is +the way Stroustrup would have done it. :-> + +The gzifstream and gzofstream classes were originally written by Kevin Ruland +and made available in the zlib contrib/iostream directory. The older version still +compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of +this version. + +The new classes are as standard-compliant as possible, closely following the +approach of the standard library's fstream classes. It compiles under gcc versions +3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard +library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs +from the previous one in the following respects: +- added showmanyc +- added setbuf, with support for unbuffered output via setbuf(0,0) +- a few bug fixes of stream behavior +- gzipped output file opened with default compression level instead of maximum level +- setcompressionlevel()/strategy() members replaced by single setcompression() + +The code is provided "as is", with the permission to use, copy, modify, distribute +and sell it for any purpose without fee. + +Ludwig Schwardt + + +DSP Lab +Electrical & Electronic Engineering Department +University of Stellenbosch +South Africa diff --git a/libz/contrib/iostream3/TODO b/libz/contrib/iostream3/TODO new file mode 100644 index 000000000..7032f97be --- /dev/null +++ b/libz/contrib/iostream3/TODO @@ -0,0 +1,17 @@ +Possible upgrades to gzfilebuf: + +- The ability to do putback (e.g. putbackfail) + +- The ability to seek (zlib supports this, but could be slow/tricky) + +- Simultaneous read/write access (does it make sense?) + +- Support for ios_base::ate open mode + +- Locale support? + +- Check public interface to see which calls give problems + (due to dependence on library internals) + +- Override operator<<(ostream&, gzfilebuf*) to allow direct copying + of stream buffer to stream ( i.e. os << is.rdbuf(); ) diff --git a/libz/contrib/iostream3/test.cc b/libz/contrib/iostream3/test.cc new file mode 100644 index 000000000..94235334f --- /dev/null +++ b/libz/contrib/iostream3/test.cc @@ -0,0 +1,50 @@ +/* + * Test program for gzifstream and gzofstream + * + * by Ludwig Schwardt + * original version by Kevin Ruland + */ + +#include "zfstream.h" +#include // for cout + +int main() { + + gzofstream outf; + gzifstream inf; + char buf[80]; + + outf.open("test1.txt.gz"); + outf << "The quick brown fox sidestepped the lazy canine\n" + << 1.3 << "\nPlan " << 9 << std::endl; + outf.close(); + std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n" + << "The quick brown fox sidestepped the lazy canine\n" + << 1.3 << "\nPlan " << 9 << std::endl; + + std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n"; + inf.open("test1.txt.gz"); + while (inf.getline(buf,80,'\n')) { + std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n"; + } + inf.close(); + + outf.rdbuf()->pubsetbuf(0,0); + outf.open("test2.txt.gz"); + outf << setcompression(Z_NO_COMPRESSION) + << "The quick brown fox sidestepped the lazy canine\n" + << 1.3 << "\nPlan " << 9 << std::endl; + outf.close(); + std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form"; + + std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n"; + inf.rdbuf()->pubsetbuf(0,0); + inf.open("test2.txt.gz"); + while (inf.getline(buf,80,'\n')) { + std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n"; + } + inf.close(); + + return 0; + +} diff --git a/libz/contrib/iostream3/zfstream.cc b/libz/contrib/iostream3/zfstream.cc new file mode 100644 index 000000000..94eb93344 --- /dev/null +++ b/libz/contrib/iostream3/zfstream.cc @@ -0,0 +1,479 @@ +/* + * A C++ I/O streams interface to the zlib gz* functions + * + * by Ludwig Schwardt + * original version by Kevin Ruland + * + * This version is standard-compliant and compatible with gcc 3.x. + */ + +#include "zfstream.h" +#include // for strcpy, strcat, strlen (mode strings) +#include // for BUFSIZ + +// Internal buffer sizes (default and "unbuffered" versions) +#define BIGBUFSIZE BUFSIZ +#define SMALLBUFSIZE 1 + +/*****************************************************************************/ + +// Default constructor +gzfilebuf::gzfilebuf() +: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false), + buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true) +{ + // No buffers to start with + this->disable_buffer(); +} + +// Destructor +gzfilebuf::~gzfilebuf() +{ + // Sync output buffer and close only if responsible for file + // (i.e. attached streams should be left open at this stage) + this->sync(); + if (own_fd) + this->close(); + // Make sure internal buffer is deallocated + this->disable_buffer(); +} + +// Set compression level and strategy +int +gzfilebuf::setcompression(int comp_level, + int comp_strategy) +{ + return gzsetparams(file, comp_level, comp_strategy); +} + +// Open gzipped file +gzfilebuf* +gzfilebuf::open(const char *name, + std::ios_base::openmode mode) +{ + // Fail if file already open + if (this->is_open()) + return NULL; + // Don't support simultaneous read/write access (yet) + if ((mode & std::ios_base::in) && (mode & std::ios_base::out)) + return NULL; + + // Build mode string for gzopen and check it [27.8.1.3.2] + char char_mode[6] = "\0\0\0\0\0"; + if (!this->open_mode(mode, char_mode)) + return NULL; + + // Attempt to open file + if ((file = gzopen(name, char_mode)) == NULL) + return NULL; + + // On success, allocate internal buffer and set flags + this->enable_buffer(); + io_mode = mode; + own_fd = true; + return this; +} + +// Attach to gzipped file +gzfilebuf* +gzfilebuf::attach(int fd, + std::ios_base::openmode mode) +{ + // Fail if file already open + if (this->is_open()) + return NULL; + // Don't support simultaneous read/write access (yet) + if ((mode & std::ios_base::in) && (mode & std::ios_base::out)) + return NULL; + + // Build mode string for gzdopen and check it [27.8.1.3.2] + char char_mode[6] = "\0\0\0\0\0"; + if (!this->open_mode(mode, char_mode)) + return NULL; + + // Attempt to attach to file + if ((file = gzdopen(fd, char_mode)) == NULL) + return NULL; + + // On success, allocate internal buffer and set flags + this->enable_buffer(); + io_mode = mode; + own_fd = false; + return this; +} + +// Close gzipped file +gzfilebuf* +gzfilebuf::close() +{ + // Fail immediately if no file is open + if (!this->is_open()) + return NULL; + // Assume success + gzfilebuf* retval = this; + // Attempt to sync and close gzipped file + if (this->sync() == -1) + retval = NULL; + if (gzclose(file) < 0) + retval = NULL; + // File is now gone anyway (postcondition [27.8.1.3.8]) + file = NULL; + own_fd = false; + // Destroy internal buffer if it exists + this->disable_buffer(); + return retval; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Convert int open mode to mode string +bool +gzfilebuf::open_mode(std::ios_base::openmode mode, + char* c_mode) const +{ + bool testb = mode & std::ios_base::binary; + bool testi = mode & std::ios_base::in; + bool testo = mode & std::ios_base::out; + bool testt = mode & std::ios_base::trunc; + bool testa = mode & std::ios_base::app; + + // Check for valid flag combinations - see [27.8.1.3.2] (Table 92) + // Original zfstream hardcoded the compression level to maximum here... + // Double the time for less than 1% size improvement seems + // excessive though - keeping it at the default level + // To change back, just append "9" to the next three mode strings + if (!testi && testo && !testt && !testa) + strcpy(c_mode, "w"); + if (!testi && testo && !testt && testa) + strcpy(c_mode, "a"); + if (!testi && testo && testt && !testa) + strcpy(c_mode, "w"); + if (testi && !testo && !testt && !testa) + strcpy(c_mode, "r"); + // No read/write mode yet +// if (testi && testo && !testt && !testa) +// strcpy(c_mode, "r+"); +// if (testi && testo && testt && !testa) +// strcpy(c_mode, "w+"); + + // Mode string should be empty for invalid combination of flags + if (strlen(c_mode) == 0) + return false; + if (testb) + strcat(c_mode, "b"); + return true; +} + +// Determine number of characters in internal get buffer +std::streamsize +gzfilebuf::showmanyc() +{ + // Calls to underflow will fail if file not opened for reading + if (!this->is_open() || !(io_mode & std::ios_base::in)) + return -1; + // Make sure get area is in use + if (this->gptr() && (this->gptr() < this->egptr())) + return std::streamsize(this->egptr() - this->gptr()); + else + return 0; +} + +// Fill get area from gzipped file +gzfilebuf::int_type +gzfilebuf::underflow() +{ + // If something is left in the get area by chance, return it + // (this shouldn't normally happen, as underflow is only supposed + // to be called when gptr >= egptr, but it serves as error check) + if (this->gptr() && (this->gptr() < this->egptr())) + return traits_type::to_int_type(*(this->gptr())); + + // If the file hasn't been opened for reading, produce error + if (!this->is_open() || !(io_mode & std::ios_base::in)) + return traits_type::eof(); + + // Attempt to fill internal buffer from gzipped file + // (buffer must be guaranteed to exist...) + int bytes_read = gzread(file, buffer, buffer_size); + // Indicates error or EOF + if (bytes_read <= 0) + { + // Reset get area + this->setg(buffer, buffer, buffer); + return traits_type::eof(); + } + // Make all bytes read from file available as get area + this->setg(buffer, buffer, buffer + bytes_read); + + // Return next character in get area + return traits_type::to_int_type(*(this->gptr())); +} + +// Write put area to gzipped file +gzfilebuf::int_type +gzfilebuf::overflow(int_type c) +{ + // Determine whether put area is in use + if (this->pbase()) + { + // Double-check pointer range + if (this->pptr() > this->epptr() || this->pptr() < this->pbase()) + return traits_type::eof(); + // Add extra character to buffer if not EOF + if (!traits_type::eq_int_type(c, traits_type::eof())) + { + *(this->pptr()) = traits_type::to_char_type(c); + this->pbump(1); + } + // Number of characters to write to file + int bytes_to_write = this->pptr() - this->pbase(); + // Overflow doesn't fail if nothing is to be written + if (bytes_to_write > 0) + { + // If the file hasn't been opened for writing, produce error + if (!this->is_open() || !(io_mode & std::ios_base::out)) + return traits_type::eof(); + // If gzipped file won't accept all bytes written to it, fail + if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write) + return traits_type::eof(); + // Reset next pointer to point to pbase on success + this->pbump(-bytes_to_write); + } + } + // Write extra character to file if not EOF + else if (!traits_type::eq_int_type(c, traits_type::eof())) + { + // If the file hasn't been opened for writing, produce error + if (!this->is_open() || !(io_mode & std::ios_base::out)) + return traits_type::eof(); + // Impromptu char buffer (allows "unbuffered" output) + char_type last_char = traits_type::to_char_type(c); + // If gzipped file won't accept this character, fail + if (gzwrite(file, &last_char, 1) != 1) + return traits_type::eof(); + } + + // If you got here, you have succeeded (even if c was EOF) + // The return value should therefore be non-EOF + if (traits_type::eq_int_type(c, traits_type::eof())) + return traits_type::not_eof(c); + else + return c; +} + +// Assign new buffer +std::streambuf* +gzfilebuf::setbuf(char_type* p, + std::streamsize n) +{ + // First make sure stuff is sync'ed, for safety + if (this->sync() == -1) + return NULL; + // If buffering is turned off on purpose via setbuf(0,0), still allocate one... + // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at + // least a buffer of size 1 (very inefficient though, therefore make it bigger?) + // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems) + if (!p || !n) + { + // Replace existing buffer (if any) with small internal buffer + this->disable_buffer(); + buffer = NULL; + buffer_size = 0; + own_buffer = true; + this->enable_buffer(); + } + else + { + // Replace existing buffer (if any) with external buffer + this->disable_buffer(); + buffer = p; + buffer_size = n; + own_buffer = false; + this->enable_buffer(); + } + return this; +} + +// Write put area to gzipped file (i.e. ensures that put area is empty) +int +gzfilebuf::sync() +{ + return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Allocate internal buffer +void +gzfilebuf::enable_buffer() +{ + // If internal buffer required, allocate one + if (own_buffer && !buffer) + { + // Check for buffered vs. "unbuffered" + if (buffer_size > 0) + { + // Allocate internal buffer + buffer = new char_type[buffer_size]; + // Get area starts empty and will be expanded by underflow as need arises + this->setg(buffer, buffer, buffer); + // Setup entire internal buffer as put area. + // The one-past-end pointer actually points to the last element of the buffer, + // so that overflow(c) can safely add the extra character c to the sequence. + // These pointers remain in place for the duration of the buffer + this->setp(buffer, buffer + buffer_size - 1); + } + else + { + // Even in "unbuffered" case, (small?) get buffer is still required + buffer_size = SMALLBUFSIZE; + buffer = new char_type[buffer_size]; + this->setg(buffer, buffer, buffer); + // "Unbuffered" means no put buffer + this->setp(0, 0); + } + } + else + { + // If buffer already allocated, reset buffer pointers just to make sure no + // stale chars are lying around + this->setg(buffer, buffer, buffer); + this->setp(buffer, buffer + buffer_size - 1); + } +} + +// Destroy internal buffer +void +gzfilebuf::disable_buffer() +{ + // If internal buffer exists, deallocate it + if (own_buffer && buffer) + { + // Preserve unbuffered status by zeroing size + if (!this->pbase()) + buffer_size = 0; + delete[] buffer; + buffer = NULL; + this->setg(0, 0, 0); + this->setp(0, 0); + } + else + { + // Reset buffer pointers to initial state if external buffer exists + this->setg(buffer, buffer, buffer); + if (buffer) + this->setp(buffer, buffer + buffer_size - 1); + else + this->setp(0, 0); + } +} + +/*****************************************************************************/ + +// Default constructor initializes stream buffer +gzifstream::gzifstream() +: std::istream(NULL), sb() +{ this->init(&sb); } + +// Initialize stream buffer and open file +gzifstream::gzifstream(const char* name, + std::ios_base::openmode mode) +: std::istream(NULL), sb() +{ + this->init(&sb); + this->open(name, mode); +} + +// Initialize stream buffer and attach to file +gzifstream::gzifstream(int fd, + std::ios_base::openmode mode) +: std::istream(NULL), sb() +{ + this->init(&sb); + this->attach(fd, mode); +} + +// Open file and go into fail() state if unsuccessful +void +gzifstream::open(const char* name, + std::ios_base::openmode mode) +{ + if (!sb.open(name, mode | std::ios_base::in)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Attach to file and go into fail() state if unsuccessful +void +gzifstream::attach(int fd, + std::ios_base::openmode mode) +{ + if (!sb.attach(fd, mode | std::ios_base::in)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Close file +void +gzifstream::close() +{ + if (!sb.close()) + this->setstate(std::ios_base::failbit); +} + +/*****************************************************************************/ + +// Default constructor initializes stream buffer +gzofstream::gzofstream() +: std::ostream(NULL), sb() +{ this->init(&sb); } + +// Initialize stream buffer and open file +gzofstream::gzofstream(const char* name, + std::ios_base::openmode mode) +: std::ostream(NULL), sb() +{ + this->init(&sb); + this->open(name, mode); +} + +// Initialize stream buffer and attach to file +gzofstream::gzofstream(int fd, + std::ios_base::openmode mode) +: std::ostream(NULL), sb() +{ + this->init(&sb); + this->attach(fd, mode); +} + +// Open file and go into fail() state if unsuccessful +void +gzofstream::open(const char* name, + std::ios_base::openmode mode) +{ + if (!sb.open(name, mode | std::ios_base::out)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Attach to file and go into fail() state if unsuccessful +void +gzofstream::attach(int fd, + std::ios_base::openmode mode) +{ + if (!sb.attach(fd, mode | std::ios_base::out)) + this->setstate(std::ios_base::failbit); + else + this->clear(); +} + +// Close file +void +gzofstream::close() +{ + if (!sb.close()) + this->setstate(std::ios_base::failbit); +} diff --git a/libz/contrib/iostream3/zfstream.h b/libz/contrib/iostream3/zfstream.h new file mode 100644 index 000000000..8574479ae --- /dev/null +++ b/libz/contrib/iostream3/zfstream.h @@ -0,0 +1,466 @@ +/* + * A C++ I/O streams interface to the zlib gz* functions + * + * by Ludwig Schwardt + * original version by Kevin Ruland + * + * This version is standard-compliant and compatible with gcc 3.x. + */ + +#ifndef ZFSTREAM_H +#define ZFSTREAM_H + +#include // not iostream, since we don't need cin/cout +#include +#include "zlib.h" + +/*****************************************************************************/ + +/** + * @brief Gzipped file stream buffer class. + * + * This class implements basic_filebuf for gzipped files. It doesn't yet support + * seeking (allowed by zlib but slow/limited), putback and read/write access + * (tricky). Otherwise, it attempts to be a drop-in replacement for the standard + * file streambuf. +*/ +class gzfilebuf : public std::streambuf +{ +public: + // Default constructor. + gzfilebuf(); + + // Destructor. + virtual + ~gzfilebuf(); + + /** + * @brief Set compression level and strategy on the fly. + * @param comp_level Compression level (see zlib.h for allowed values) + * @param comp_strategy Compression strategy (see zlib.h for allowed values) + * @return Z_OK on success, Z_STREAM_ERROR otherwise. + * + * Unfortunately, these parameters cannot be modified separately, as the + * previous zfstream version assumed. Since the strategy is seldom changed, + * it can default and setcompression(level) then becomes like the old + * setcompressionlevel(level). + */ + int + setcompression(int comp_level, + int comp_strategy = Z_DEFAULT_STRATEGY); + + /** + * @brief Check if file is open. + * @return True if file is open. + */ + bool + is_open() const { return (file != NULL); } + + /** + * @brief Open gzipped file. + * @param name File name. + * @param mode Open mode flags. + * @return @c this on success, NULL on failure. + */ + gzfilebuf* + open(const char* name, + std::ios_base::openmode mode); + + /** + * @brief Attach to already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags. + * @return @c this on success, NULL on failure. + */ + gzfilebuf* + attach(int fd, + std::ios_base::openmode mode); + + /** + * @brief Close gzipped file. + * @return @c this on success, NULL on failure. + */ + gzfilebuf* + close(); + +protected: + /** + * @brief Convert ios open mode int to mode string used by zlib. + * @return True if valid mode flag combination. + */ + bool + open_mode(std::ios_base::openmode mode, + char* c_mode) const; + + /** + * @brief Number of characters available in stream buffer. + * @return Number of characters. + * + * This indicates number of characters in get area of stream buffer. + * These characters can be read without accessing the gzipped file. + */ + virtual std::streamsize + showmanyc(); + + /** + * @brief Fill get area from gzipped file. + * @return First character in get area on success, EOF on error. + * + * This actually reads characters from gzipped file to stream + * buffer. Always buffered. + */ + virtual int_type + underflow(); + + /** + * @brief Write put area to gzipped file. + * @param c Extra character to add to buffer contents. + * @return Non-EOF on success, EOF on error. + * + * This actually writes characters in stream buffer to + * gzipped file. With unbuffered output this is done one + * character at a time. + */ + virtual int_type + overflow(int_type c = traits_type::eof()); + + /** + * @brief Installs external stream buffer. + * @param p Pointer to char buffer. + * @param n Size of external buffer. + * @return @c this on success, NULL on failure. + * + * Call setbuf(0,0) to enable unbuffered output. + */ + virtual std::streambuf* + setbuf(char_type* p, + std::streamsize n); + + /** + * @brief Flush stream buffer to file. + * @return 0 on success, -1 on error. + * + * This calls underflow(EOF) to do the job. + */ + virtual int + sync(); + +// +// Some future enhancements +// +// virtual int_type uflow(); +// virtual int_type pbackfail(int_type c = traits_type::eof()); +// virtual pos_type +// seekoff(off_type off, +// std::ios_base::seekdir way, +// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out); +// virtual pos_type +// seekpos(pos_type sp, +// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out); + +private: + /** + * @brief Allocate internal buffer. + * + * This function is safe to call multiple times. It will ensure + * that a proper internal buffer exists if it is required. If the + * buffer already exists or is external, the buffer pointers will be + * reset to their original state. + */ + void + enable_buffer(); + + /** + * @brief Destroy internal buffer. + * + * This function is safe to call multiple times. It will ensure + * that the internal buffer is deallocated if it exists. In any + * case, it will also reset the buffer pointers. + */ + void + disable_buffer(); + + /** + * Underlying file pointer. + */ + gzFile file; + + /** + * Mode in which file was opened. + */ + std::ios_base::openmode io_mode; + + /** + * @brief True if this object owns file descriptor. + * + * This makes the class responsible for closing the file + * upon destruction. + */ + bool own_fd; + + /** + * @brief Stream buffer. + * + * For simplicity this remains allocated on the free store for the + * entire life span of the gzfilebuf object, unless replaced by setbuf. + */ + char_type* buffer; + + /** + * @brief Stream buffer size. + * + * Defaults to system default buffer size (typically 8192 bytes). + * Modified by setbuf. + */ + std::streamsize buffer_size; + + /** + * @brief True if this object owns stream buffer. + * + * This makes the class responsible for deleting the buffer + * upon destruction. + */ + bool own_buffer; +}; + +/*****************************************************************************/ + +/** + * @brief Gzipped file input stream class. + * + * This class implements ifstream for gzipped files. Seeking and putback + * is not supported yet. +*/ +class gzifstream : public std::istream +{ +public: + // Default constructor + gzifstream(); + + /** + * @brief Construct stream on gzipped file to be opened. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::in). + */ + explicit + gzifstream(const char* name, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * @brief Construct stream on already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::in). + */ + explicit + gzifstream(int fd, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * Obtain underlying stream buffer. + */ + gzfilebuf* + rdbuf() const + { return const_cast(&sb); } + + /** + * @brief Check if file is open. + * @return True if file is open. + */ + bool + is_open() { return sb.is_open(); } + + /** + * @brief Open gzipped file. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::in). + * + * Stream will be in state good() if file opens successfully; + * otherwise in state fail(). This differs from the behavior of + * ifstream, which never sets the state to good() and therefore + * won't allow you to reuse the stream for a second file unless + * you manually clear() the state. The choice is a matter of + * convenience. + */ + void + open(const char* name, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * @brief Attach to already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::in). + * + * Stream will be in state good() if attach succeeded; otherwise + * in state fail(). + */ + void + attach(int fd, + std::ios_base::openmode mode = std::ios_base::in); + + /** + * @brief Close gzipped file. + * + * Stream will be in state fail() if close failed. + */ + void + close(); + +private: + /** + * Underlying stream buffer. + */ + gzfilebuf sb; +}; + +/*****************************************************************************/ + +/** + * @brief Gzipped file output stream class. + * + * This class implements ofstream for gzipped files. Seeking and putback + * is not supported yet. +*/ +class gzofstream : public std::ostream +{ +public: + // Default constructor + gzofstream(); + + /** + * @brief Construct stream on gzipped file to be opened. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::out). + */ + explicit + gzofstream(const char* name, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * @brief Construct stream on already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::out). + */ + explicit + gzofstream(int fd, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * Obtain underlying stream buffer. + */ + gzfilebuf* + rdbuf() const + { return const_cast(&sb); } + + /** + * @brief Check if file is open. + * @return True if file is open. + */ + bool + is_open() { return sb.is_open(); } + + /** + * @brief Open gzipped file. + * @param name File name. + * @param mode Open mode flags (forced to contain ios::out). + * + * Stream will be in state good() if file opens successfully; + * otherwise in state fail(). This differs from the behavior of + * ofstream, which never sets the state to good() and therefore + * won't allow you to reuse the stream for a second file unless + * you manually clear() the state. The choice is a matter of + * convenience. + */ + void + open(const char* name, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * @brief Attach to already open gzipped file. + * @param fd File descriptor. + * @param mode Open mode flags (forced to contain ios::out). + * + * Stream will be in state good() if attach succeeded; otherwise + * in state fail(). + */ + void + attach(int fd, + std::ios_base::openmode mode = std::ios_base::out); + + /** + * @brief Close gzipped file. + * + * Stream will be in state fail() if close failed. + */ + void + close(); + +private: + /** + * Underlying stream buffer. + */ + gzfilebuf sb; +}; + +/*****************************************************************************/ + +/** + * @brief Gzipped file output stream manipulator class. + * + * This class defines a two-argument manipulator for gzofstream. It is used + * as base for the setcompression(int,int) manipulator. +*/ +template + class gzomanip2 + { + public: + // Allows insertor to peek at internals + template + friend gzofstream& + operator<<(gzofstream&, + const gzomanip2&); + + // Constructor + gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2), + T1 v1, + T2 v2); + private: + // Underlying manipulator function + gzofstream& + (*func)(gzofstream&, T1, T2); + + // Arguments for manipulator function + T1 val1; + T2 val2; + }; + +/*****************************************************************************/ + +// Manipulator function thunks through to stream buffer +inline gzofstream& +setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY) +{ + (gzs.rdbuf())->setcompression(l, s); + return gzs; +} + +// Manipulator constructor stores arguments +template + inline + gzomanip2::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2), + T1 v1, + T2 v2) + : func(f), val1(v1), val2(v2) + { } + +// Insertor applies underlying manipulator function to stream +template + inline gzofstream& + operator<<(gzofstream& s, const gzomanip2& m) + { return (*m.func)(s, m.val1, m.val2); } + +// Insert this onto stream to simplify setting of compression level +inline gzomanip2 +setcompression(int l, int s = Z_DEFAULT_STRATEGY) +{ return gzomanip2(&setcompression, l, s); } + +#endif // ZFSTREAM_H diff --git a/libz/contrib/masmx64/bld_ml64.bat b/libz/contrib/masmx64/bld_ml64.bat new file mode 100644 index 000000000..8f9343d0a --- /dev/null +++ b/libz/contrib/masmx64/bld_ml64.bat @@ -0,0 +1,2 @@ +ml64.exe /Flinffasx64 /c /Zi inffasx64.asm +ml64.exe /Flgvmat64 /c /Zi gvmat64.asm diff --git a/libz/contrib/masmx64/gvmat64.asm b/libz/contrib/masmx64/gvmat64.asm new file mode 100644 index 000000000..9879c28b9 --- /dev/null +++ b/libz/contrib/masmx64/gvmat64.asm @@ -0,0 +1,553 @@ +;uInt longest_match_x64( +; deflate_state *s, +; IPos cur_match); /* current match */ + +; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86_64 +; (AMD64 on Athlon 64, Opteron, Phenom +; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7) +; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; +; File written by Gilles Vollant, by converting to assembly the longest_match +; from Jean-loup Gailly in deflate.c of zLib and infoZip zip. +; +; and by taking inspiration on asm686 with masm, optimised assembly code +; from Brian Raiter, written 1998 +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Permission is granted to anyone to use this software for any purpose, +; including commercial applications, and to alter it and redistribute it +; freely, subject to the following restrictions: +; +; 1. The origin of this software must not be misrepresented; you must not +; claim that you wrote the original software. If you use this software +; in a product, an acknowledgment in the product documentation would be +; appreciated but is not required. +; 2. Altered source versions must be plainly marked as such, and must not be +; misrepresented as being the original software +; 3. This notice may not be removed or altered from any source distribution. +; +; +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; to compile this file for infozip Zip, I use option: +; ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm +; +; to compile this file for zLib, I use option: +; ml64.exe /Flgvmat64 /c /Zi gvmat64.asm +; Be carrefull to adapt zlib1222add below to your version of zLib +; (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change +; value of zlib1222add later) +; +; This file compile with Microsoft Macro Assembler (x64) for AMD64 +; +; ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK +; +; (you can get Windows WDK with ml64 for AMD64 from +; http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price) +; + + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; /* current match */ +.code +longest_match PROC + + +;LocalVarsSize equ 88 + LocalVarsSize equ 72 + +; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12 +; free register : r14,r15 +; register can be saved : rsp + + chainlenwmask equ rsp + 8 - LocalVarsSize ; high word: current chain len + ; low word: s->wmask +;window equ rsp + xx - LocalVarsSize ; local copy of s->window ; stored in r10 +;windowbestlen equ rsp + xx - LocalVarsSize ; s->window + bestlen , use r10+r11 +;scanstart equ rsp + xx - LocalVarsSize ; first two bytes of string ; stored in r12w +;scanend equ rsp + xx - LocalVarsSize ; last two bytes of string use ebx +;scanalign equ rsp + xx - LocalVarsSize ; dword-misalignment of string r13 +;bestlen equ rsp + xx - LocalVarsSize ; size of best match so far -> r11d +;scan equ rsp + xx - LocalVarsSize ; ptr to string wanting match -> r9 +IFDEF INFOZIP +ELSE + nicematch equ (rsp + 16 - LocalVarsSize) ; a good enough match size +ENDIF + +save_rdi equ rsp + 24 - LocalVarsSize +save_rsi equ rsp + 32 - LocalVarsSize +save_rbx equ rsp + 40 - LocalVarsSize +save_rbp equ rsp + 48 - LocalVarsSize +save_r12 equ rsp + 56 - LocalVarsSize +save_r13 equ rsp + 64 - LocalVarsSize +;save_r14 equ rsp + 72 - LocalVarsSize +;save_r15 equ rsp + 80 - LocalVarsSize + + +; summary of register usage +; scanend ebx +; scanendw bx +; chainlenwmask edx +; curmatch rsi +; curmatchd esi +; windowbestlen r8 +; scanalign r9 +; scanalignd r9d +; window r10 +; bestlen r11 +; bestlend r11d +; scanstart r12d +; scanstartw r12w +; scan r13 +; nicematch r14d +; limit r15 +; limitd r15d +; prev rcx + +; all the +4 offsets are due to the addition of pending_buf_size (in zlib +; in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, remove the +4). +; Note : these value are good with a 8 bytes boundary pack structure + + + MAX_MATCH equ 258 + MIN_MATCH equ 3 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + + +IFDEF INFOZIP + +_DATA SEGMENT +COMM window_size:DWORD +; WMask ; 7fff +COMM window:BYTE:010040H +COMM prev:WORD:08000H +; MatchLen : unused +; PrevMatch : unused +COMM strstart:DWORD +COMM match_start:DWORD +; Lookahead : ignore +COMM prev_length:DWORD ; PrevLen +COMM max_chain_length:DWORD +COMM good_match:DWORD +COMM nice_match:DWORD +prev_ad equ OFFSET prev +window_ad equ OFFSET window +nicematch equ nice_match +_DATA ENDS +WMask equ 07fffh + +ELSE + + IFNDEF zlib1222add + zlib1222add equ 8 + ENDIF +dsWSize equ 56+zlib1222add+(zlib1222add/2) +dsWMask equ 64+zlib1222add+(zlib1222add/2) +dsWindow equ 72+zlib1222add +dsPrev equ 88+zlib1222add +dsMatchLen equ 128+zlib1222add +dsPrevMatch equ 132+zlib1222add +dsStrStart equ 140+zlib1222add +dsMatchStart equ 144+zlib1222add +dsLookahead equ 148+zlib1222add +dsPrevLen equ 152+zlib1222add +dsMaxChainLen equ 156+zlib1222add +dsGoodMatch equ 172+zlib1222add +dsNiceMatch equ 176+zlib1222add + +window_size equ [ rcx + dsWSize] +WMask equ [ rcx + dsWMask] +window_ad equ [ rcx + dsWindow] +prev_ad equ [ rcx + dsPrev] +strstart equ [ rcx + dsStrStart] +match_start equ [ rcx + dsMatchStart] +Lookahead equ [ rcx + dsLookahead] ; 0ffffffffh on infozip +prev_length equ [ rcx + dsPrevLen] +max_chain_length equ [ rcx + dsMaxChainLen] +good_match equ [ rcx + dsGoodMatch] +nice_match equ [ rcx + dsNiceMatch] +ENDIF + +; parameter 1 in r8(deflate state s), param 2 in rdx (cur match) + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch. + + + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + +;;; Retrieve the function arguments. r8d will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + +; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match) + +; this clear high 32 bits of r8, which can be garbage in both r8 and rdx + + mov [save_rdi],rdi + mov [save_rsi],rsi + mov [save_rbx],rbx + mov [save_rbp],rbp +IFDEF INFOZIP + mov r8d,ecx +ELSE + mov r8d,edx +ENDIF + mov [save_r12],r12 + mov [save_r13],r13 +; mov [save_r14],r14 +; mov [save_r15],r15 + + +;;; uInt wmask = s->w_mask; +;;; unsigned chain_length = s->max_chain_length; +;;; if (s->prev_length >= s->good_match) { +;;; chain_length >>= 2; +;;; } + + mov edi, prev_length + mov esi, good_match + mov eax, WMask + mov ebx, max_chain_length + cmp edi, esi + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +;;; chainlen is decremented once beforehand so that the function can +;;; use the sign flag instead of the zero flag for the exit test. +;;; It is then shifted into the high word, to make room for the wmask +;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + +;;; on zlib only +;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + +IFDEF INFOZIP + mov [chainlenwmask], ebx +; on infozip nice_match = [nice_match] +ELSE + mov eax, nice_match + mov [chainlenwmask], ebx + mov r10d, Lookahead + cmp r10d, eax + cmovnl r10d, eax + mov [nicematch],r10d +ENDIF + +;;; register Bytef *scan = s->window + s->strstart; + mov r10, window_ad + mov ebp, strstart + lea r13, [r10 + rbp] + +;;; Determine how many bytes the scan ptr is off from being +;;; dword-aligned. + + mov r9,r13 + neg r13 + and r13,3 + +;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +;;; s->strstart - (IPos)MAX_DIST(s) : NIL; +IFDEF INFOZIP + mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1)) +ELSE + mov eax, window_size + sub eax, MIN_LOOKAHEAD +ENDIF + xor edi,edi + sub ebp, eax + + mov r11d, prev_length + + cmovng ebp,edi + +;;; int best_len = s->prev_length; + + +;;; Store the sum of s->window + best_len in esi locally, and in esi. + + lea rsi,[r10+r11] + +;;; register ush scan_start = *(ushf*)scan; +;;; register ush scan_end = *(ushf*)(scan+best_len-1); +;;; Posf *prev = s->prev; + + movzx r12d,word ptr [r9] + movzx ebx, word ptr [r9 + r11 - 1] + + mov rdi, prev_ad + +;;; Jump into the main loop. + + mov edx, [chainlenwmask] + + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop1: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry1: + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop2: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry2: + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop4: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry4: + + cmp bx,word ptr [rsi + r8 - 1] + jnz LookupLoop1 + jmp LookupLoopIsZero + + +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; r8d = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit + +LookupLoop: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry: + + cmp bx,word ptr [rsi + r8 - 1] + jnz LookupLoop1 +LookupLoopIsZero: + cmp r12w, word ptr [r10 + r8] + jnz LookupLoop1 + + +;;; Store the current value of chainlen. + mov [chainlenwmask], edx + +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). + + lea rsi,[r8+r10] + mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8) + lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8] + lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8] + + prefetcht1 [rsi+rdx] + prefetcht1 [rdi+rdx] + + +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust rdx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (rsi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. + + +LoopCmps: + mov rax, [rsi + rdx] + xor rax, [rdi + rdx] + jnz LeaveLoopCmps + + mov rax, [rsi + rdx + 8] + xor rax, [rdi + rdx + 8] + jnz LeaveLoopCmps8 + + + mov rax, [rsi + rdx + 8+8] + xor rax, [rdi + rdx + 8+8] + jnz LeaveLoopCmps16 + + add rdx,8+8+8 + + jnz short LoopCmps + jmp short LenMaximum +LeaveLoopCmps16: add rdx,8 +LeaveLoopCmps8: add rdx,8 +LeaveLoopCmps: + + test eax, 0000FFFFh + jnz LenLower + + test eax,0ffffffffh + + jnz LenLower32 + + add rdx,4 + shr rax,32 + or ax,ax + jnz LenLower + +LenLower32: + shr eax,16 + add rdx,2 +LenLower: sub al, 1 + adc rdx, 0 +;;; Calculate the length of the match. If it is longer than MAX_MATCH, +;;; then automatically accept it as the best possible match and leave. + + lea rax, [rdi + rdx] + sub rax, r9 + cmp eax, MAX_MATCH + jge LenMaximum + +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. +;/////////////////////////////////// + + cmp eax, r11d + jg LongerMatch + + lea rsi,[r10+r11] + + mov rdi, prev_ad + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); + +LongerMatch: + mov r11d, eax + mov match_start, r8d + cmp eax, [nicematch] + jge LeaveNow + + lea rsi,[r10+rax] + + movzx ebx, word ptr [r9 + rax - 1] + mov rdi, prev_ad + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; Accept the current string, with the maximum possible length. + +LenMaximum: + mov r11d,MAX_MATCH + mov match_start, r8d + +;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +;;; return s->lookahead; + +LeaveNow: +IFDEF INFOZIP + mov eax,r11d +ELSE + mov eax, Lookahead + cmp r11d, eax + cmovng eax, r11d +ENDIF + +;;; Restore the stack and return from whence we came. + + + mov rsi,[save_rsi] + mov rdi,[save_rdi] + mov rbx,[save_rbx] + mov rbp,[save_rbp] + mov r12,[save_r12] + mov r13,[save_r13] +; mov r14,[save_r14] +; mov r15,[save_r15] + + + ret 0 +; please don't remove this string ! +; Your can freely use gvmat64 in any free or commercial app +; but it is far better don't remove the string in the binary! + db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0 +longest_match ENDP + +match_init PROC + ret 0 +match_init ENDP + + +END diff --git a/libz/contrib/masmx64/inffas8664.c b/libz/contrib/masmx64/inffas8664.c new file mode 100644 index 000000000..e8af06fa0 --- /dev/null +++ b/libz/contrib/masmx64/inffas8664.c @@ -0,0 +1,186 @@ +/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding + * version for AMD64 on Windows using Microsoft C compiler + * + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant + * + * inffas8664.c call function inffas8664fnc in inffasx64.asm + * inffasx64.asm is automatically convert from AMD64 portion of inffas86.c + * + * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also + * slightly quicker on x86 systems because, instead of using rep movsb to copy + * data, it uses rep movsw, which moves data in 2-byte chunks instead of single + * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates + * from http://fedora.linux.duke.edu/fc1_x86_64 + * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with + * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version, + * when decompressing mozilla-source-1.3.tar.gz. + * + * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from + * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at + * the moment. I have successfully compiled and tested this code with gcc2.96, + * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S + * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX + * enabled. I will attempt to merge the MMX code into this version. Newer + * versions of this and inffast.S can be found at + * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ + * + */ + +#include +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* Mark Adler's comments from inffast.c: */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ + + + + typedef struct inffast_ar { +/* 64 32 x86 x86_64 */ +/* ar offset register */ +/* 0 0 */ void *esp; /* esp save */ +/* 8 4 */ void *ebp; /* ebp save */ +/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */ +/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */ +/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */ +/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */ +/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */ +/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */ +/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */ +/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */ +/* 80 40 */ size_t /*unsigned long */hold; /* edx rdx local strm->hold */ +/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */ +/* 92 48 */ unsigned wsize; /* window size */ +/* 96 52 */ unsigned write; /* window write index */ +/*100 56 */ unsigned lmask; /* r12 mask for lcode */ +/*104 60 */ unsigned dmask; /* r13 mask for dcode */ +/*108 64 */ unsigned len; /* r14 match length */ +/*112 68 */ unsigned dist; /* r15 match distance */ +/*116 72 */ unsigned status; /* set when state chng*/ + } type_ar; +#ifdef ASMINF + +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + type_ar ar; + void inffas8664fnc(struct inffast_ar * par); + + + +#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64)) +#define PAD_AVAIL_IN 6 +#define PAD_AVAIL_OUT 258 +#else +#define PAD_AVAIL_IN 5 +#define PAD_AVAIL_OUT 257 +#endif + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + + ar.in = strm->next_in; + ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN); + ar.out = strm->next_out; + ar.beg = ar.out - (start - strm->avail_out); + ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT); + ar.wsize = state->wsize; + ar.write = state->wnext; + ar.window = state->window; + ar.hold = state->hold; + ar.bits = state->bits; + ar.lcode = state->lencode; + ar.dcode = state->distcode; + ar.lmask = (1U << state->lenbits) - 1; + ar.dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + /* align in on 1/2 hold size boundary */ + while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) { + ar.hold += (unsigned long)*ar.in++ << ar.bits; + ar.bits += 8; + } + + inffas8664fnc(&ar); + + if (ar.status > 1) { + if (ar.status == 2) + strm->msg = "invalid literal/length code"; + else if (ar.status == 3) + strm->msg = "invalid distance code"; + else + strm->msg = "invalid distance too far back"; + state->mode = BAD; + } + else if ( ar.status == 1 ) { + state->mode = TYPE; + } + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + ar.len = ar.bits >> 3; + ar.in -= ar.len; + ar.bits -= ar.len << 3; + ar.hold &= (1U << ar.bits) - 1; + + /* update state and return */ + strm->next_in = ar.in; + strm->next_out = ar.out; + strm->avail_in = (unsigned)(ar.in < ar.last ? + PAD_AVAIL_IN + (ar.last - ar.in) : + PAD_AVAIL_IN - (ar.in - ar.last)); + strm->avail_out = (unsigned)(ar.out < ar.end ? + PAD_AVAIL_OUT + (ar.end - ar.out) : + PAD_AVAIL_OUT - (ar.out - ar.end)); + state->hold = (unsigned long)ar.hold; + state->bits = ar.bits; + return; +} + +#endif diff --git a/libz/contrib/masmx64/inffasx64.asm b/libz/contrib/masmx64/inffasx64.asm new file mode 100644 index 000000000..60a8d89b7 --- /dev/null +++ b/libz/contrib/masmx64/inffasx64.asm @@ -0,0 +1,396 @@ +; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding +; version for AMD64 on Windows using Microsoft C compiler +; +; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c +; inffasx64.asm is called by inffas8664.c, which contain more info. + + +; to compile this file, I use option +; ml64.exe /Flinffasx64 /c /Zi inffasx64.asm +; with Microsoft Macro Assembler (x64) for AMD64 +; + +; This file compile with Microsoft Macro Assembler (x64) for AMD64 +; +; ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK +; +; (you can get Windows WDK with ml64 for AMD64 from +; http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price) +; + + +.code +inffas8664fnc PROC + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch. + + + mov [rsp-8],rsi + mov [rsp-16],rdi + mov [rsp-24],r12 + mov [rsp-32],r13 + mov [rsp-40],r14 + mov [rsp-48],r15 + mov [rsp-56],rbx + + mov rax,rcx + + mov [rax+8], rbp ; /* save regs rbp and rsp */ + mov [rax], rsp + + mov rsp, rax ; /* make rsp point to &ar */ + + mov rsi, [rsp+16] ; /* rsi = in */ + mov rdi, [rsp+32] ; /* rdi = out */ + mov r9, [rsp+24] ; /* r9 = last */ + mov r10, [rsp+48] ; /* r10 = end */ + mov rbp, [rsp+64] ; /* rbp = lcode */ + mov r11, [rsp+72] ; /* r11 = dcode */ + mov rdx, [rsp+80] ; /* rdx = hold */ + mov ebx, [rsp+88] ; /* ebx = bits */ + mov r12d, [rsp+100] ; /* r12d = lmask */ + mov r13d, [rsp+104] ; /* r13d = dmask */ + ; /* r14d = len */ + ; /* r15d = dist */ + + + cld + cmp r10, rdi + je L_one_time ; /* if only one decode left */ + cmp r9, rsi + + jne L_do_loop + + +L_one_time: + mov r8, r12 ; /* r8 = lmask */ + cmp bl, 32 + ja L_get_length_code_one_time + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + jmp L_get_length_code_one_time + +ALIGN 4 +L_while_test: + cmp r10, rdi + jbe L_break_loop + cmp r9, rsi + jbe L_break_loop + +L_do_loop: + mov r8, r12 ; /* r8 = lmask */ + cmp bl, 32 + ja L_get_length_code ; /* if (32 < bits) */ + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + +L_get_length_code: + and r8, rdx ; /* r8 &= hold */ + mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */ + + mov cl, ah ; /* cl = this.bits */ + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base ; /* if (op != 0) 45.7% */ + + mov r8, r12 ; /* r8 = lmask */ + shr eax, 16 ; /* output this.val char */ + stosb + +L_get_length_code_one_time: + and r8, rdx ; /* r8 &= hold */ + mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */ + +L_dolen: + mov cl, ah ; /* cl = this.bits */ + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base ; /* if (op != 0) 45.7% */ + + shr eax, 16 ; /* output this.val char */ + stosb + jmp L_while_test + +ALIGN 4 +L_test_for_length_base: + mov r14d, eax ; /* len = this */ + shr r14d, 16 ; /* len = this.val */ + mov cl, al + + test al, 16 + jz L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */ + and cl, 15 ; /* op &= 15 */ + jz L_decode_distance ; /* if (!op) */ + +L_add_bits_to_len: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + shr rdx, cl + add r14d, eax ; /* len += hold & mask[op] */ + +L_decode_distance: + mov r8, r13 ; /* r8 = dmask */ + cmp bl, 32 + ja L_get_distance_code ; /* if (32 < bits) */ + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + +L_get_distance_code: + and r8, rdx ; /* r8 &= hold */ + mov eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */ + +L_dodist: + mov r15d, eax ; /* dist = this */ + shr r15d, 16 ; /* dist = this.val */ + mov cl, ah + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + mov cl, al ; /* cl = this.op */ + + test al, 16 ; /* if ((op & 16) == 0) */ + jz L_test_for_second_level_dist + and cl, 15 ; /* op &= 15 */ + jz L_check_dist_one + +L_add_bits_to_dist: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax ; /* (1 << op) - 1 */ + and eax, edx ; /* eax &= hold */ + shr rdx, cl + add r15d, eax ; /* dist += hold & ((1 << op) - 1) */ + +L_check_window: + mov r8, rsi ; /* save in so from can use it's reg */ + mov rax, rdi + sub rax, [rsp+40] ; /* nbytes = out - beg */ + + cmp eax, r15d + jb L_clip_window ; /* if (dist > nbytes) 4.2% */ + + mov ecx, r14d ; /* ecx = len */ + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + + sar ecx, 1 + jnc L_copy_two ; /* if len % 2 == 0 */ + + rep movsw + mov al, [rsi] + mov [rdi], al + inc rdi + + mov rsi, r8 ; /* move in back to %rsi, toss from */ + jmp L_while_test + +L_copy_two: + rep movsw + mov rsi, r8 ; /* move in back to %rsi, toss from */ + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp r15d, 1 ; /* if dist 1, is a memset */ + jne L_check_window + cmp [rsp+40], rdi ; /* if out == beg, outside window */ + je L_check_window + + mov ecx, r14d ; /* ecx = len */ + mov al, [rdi-1] + mov ah, al + + sar ecx, 1 + jnc L_set_two + mov [rdi], al + inc rdi + +L_set_two: + rep stosw + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + test al, 64 + jnz L_test_for_end_of_block ; /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + add eax, r14d ; /* eax += len */ + mov eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/ + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + test al, 64 + jnz L_invalid_distance_code ; /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + add eax, r15d ; /* eax += dist */ + mov eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/ + jmp L_dodist + +ALIGN 4 +L_clip_window: + mov ecx, eax ; /* ecx = nbytes */ + mov eax, [rsp+92] ; /* eax = wsize, prepare for dist cmp */ + neg ecx ; /* nbytes = -nbytes */ + + cmp eax, r15d + jb L_invalid_distance_too_far ; /* if (dist > wsize) */ + + add ecx, r15d ; /* nbytes = dist - nbytes */ + cmp dword ptr [rsp+96], 0 + jne L_wrap_around_window ; /* if (write != 0) */ + + mov rsi, [rsp+56] ; /* from = window */ + sub eax, ecx ; /* eax -= nbytes */ + add rsi, rax ; /* from += wsize - nbytes */ + + mov eax, r14d ; /* eax = len */ + cmp r14d, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* eax -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = &out[ -dist ] */ + jmp L_do_copy + +ALIGN 4 +L_wrap_around_window: + mov eax, [rsp+96] ; /* eax = write */ + cmp ecx, eax + jbe L_contiguous_in_window ; /* if (write >= nbytes) */ + + mov esi, [rsp+92] ; /* from = wsize */ + add rsi, [rsp+56] ; /* from += window */ + add rsi, rax ; /* from += write */ + sub rsi, rcx ; /* from -= nbytes */ + sub ecx, eax ; /* nbytes -= write */ + + mov eax, r14d ; /* eax = len */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, [rsp+56] ; /* from = window */ + mov ecx, [rsp+96] ; /* nbytes = write */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_contiguous_in_window: + mov rsi, [rsp+56] ; /* rsi = window */ + add rsi, rax + sub rsi, rcx ; /* from += write - nbytes */ + + mov eax, r14d ; /* eax = len */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + jmp L_do_copy ; /* if (nbytes >= len) */ + +ALIGN 4 +L_do_copy: + mov ecx, eax ; /* ecx = len */ + rep movsb + + mov rsi, r8 ; /* move in back to %esi, toss from */ + jmp L_while_test + +L_test_for_end_of_block: + test al, 32 + jz L_invalid_literal_length_code + mov dword ptr [rsp+116], 1 + jmp L_break_loop_with_status + +L_invalid_literal_length_code: + mov dword ptr [rsp+116], 2 + jmp L_break_loop_with_status + +L_invalid_distance_code: + mov dword ptr [rsp+116], 3 + jmp L_break_loop_with_status + +L_invalid_distance_too_far: + mov dword ptr [rsp+116], 4 + jmp L_break_loop_with_status + +L_break_loop: + mov dword ptr [rsp+116], 0 + +L_break_loop_with_status: +; /* put in, out, bits, and hold back into ar and pop esp */ + mov [rsp+16], rsi ; /* in */ + mov [rsp+32], rdi ; /* out */ + mov [rsp+88], ebx ; /* bits */ + mov [rsp+80], rdx ; /* hold */ + + mov rax, [rsp] ; /* restore rbp and rsp */ + mov rbp, [rsp+8] + mov rsp, rax + + + + mov rsi,[rsp-8] + mov rdi,[rsp-16] + mov r12,[rsp-24] + mov r13,[rsp-32] + mov r14,[rsp-40] + mov r15,[rsp-48] + mov rbx,[rsp-56] + + ret 0 +; : +; : "m" (ar) +; : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", +; "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" +; ); + +inffas8664fnc ENDP +;_TEXT ENDS +END diff --git a/libz/contrib/masmx64/readme.txt b/libz/contrib/masmx64/readme.txt new file mode 100644 index 000000000..2da673341 --- /dev/null +++ b/libz/contrib/masmx64/readme.txt @@ -0,0 +1,31 @@ +Summary +------- +This directory contains ASM implementations of the functions +longest_match() and inflate_fast(), for 64 bits x86 (both AMD64 and Intel EM64t), +for use with Microsoft Macro Assembler (x64) for AMD64 and Microsoft C++ 64 bits. + +gvmat64.asm is written by Gilles Vollant (2005), by using Brian Raiter 686/32 bits + assembly optimized version from Jean-loup Gailly original longest_match function + +inffasx64.asm and inffas8664.c were written by Chris Anderson, by optimizing + original function from Mark Adler + +Use instructions +---------------- +Assemble the .asm files using MASM and put the object files into the zlib source +directory. You can also get object files here: + + http://www.winimage.com/zLibDll/zlib124_masm_obj.zip + +define ASMV and ASMINF in your project. Include inffas8664.c in your source tree, +and inffasx64.obj and gvmat64.obj as object to link. + + +Build instructions +------------------ +run bld_64.bat with Microsoft Macro Assembler (x64) for AMD64 (ml64.exe) + +ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK + +You can get Windows 2003 server DDK with ml64 and cl for AMD64 from + http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price) diff --git a/libz/contrib/masmx86/bld_ml32.bat b/libz/contrib/masmx86/bld_ml32.bat new file mode 100644 index 000000000..74726337c --- /dev/null +++ b/libz/contrib/masmx86/bld_ml32.bat @@ -0,0 +1,2 @@ +ml /safeseh /coff /Zi /c /Flmatch686.lst match686.asm +ml /safeseh /coff /Zi /c /Flinffas32.lst inffas32.asm diff --git a/libz/contrib/masmx86/inffas32.asm b/libz/contrib/masmx86/inffas32.asm new file mode 100644 index 000000000..03d20f838 --- /dev/null +++ b/libz/contrib/masmx86/inffas32.asm @@ -0,0 +1,1080 @@ +;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding +; * +; * inffas32.asm is derivated from inffas86.c, with translation of assembly code +; * +; * Copyright (C) 1995-2003 Mark Adler +; * For conditions of distribution and use, see copyright notice in zlib.h +; * +; * Copyright (C) 2003 Chris Anderson +; * Please use the copyright conditions above. +; * +; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from +; * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at +; * the moment. I have successfully compiled and tested this code with gcc2.96, +; * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S +; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX +; * enabled. I will attempt to merge the MMX code into this version. Newer +; * versions of this and inffast.S can be found at +; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ +; * +; * 2005 : modification by Gilles Vollant +; */ +; For Visual C++ 4.x and higher and ML 6.x and higher +; ml.exe is in directory \MASM611C of Win95 DDK +; ml.exe is also distributed in http://www.masm32.com/masmdl.htm +; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/ +; +; +; compile with command line option +; ml /coff /Zi /c /Flinffas32.lst inffas32.asm + +; if you define NO_GZIP (see inflate.h), compile with +; ml /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm + + +; zlib122sup is 0 fort zlib 1.2.2.1 and lower +; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head +; in inflate_state in inflate.h) +zlib1222sup equ 8 + + +IFDEF GUNZIP + INFLATE_MODE_TYPE equ 11 + INFLATE_MODE_BAD equ 26 +ELSE + IFNDEF NO_GUNZIP + INFLATE_MODE_TYPE equ 11 + INFLATE_MODE_BAD equ 26 + ELSE + INFLATE_MODE_TYPE equ 3 + INFLATE_MODE_BAD equ 17 + ENDIF +ENDIF + + +; 75 "inffast.S" +;FILE "inffast.S" + +;;;GLOBAL _inflate_fast + +;;;SECTION .text + + + + .586p + .mmx + + name inflate_fast_x86 + .MODEL FLAT + +_DATA segment +inflate_fast_use_mmx: + dd 1 + + +_TEXT segment + + + +ALIGN 4 + db 'Fast decoding Code from Chris Anderson' + db 0 + +ALIGN 4 +invalid_literal_length_code_msg: + db 'invalid literal/length code' + db 0 + +ALIGN 4 +invalid_distance_code_msg: + db 'invalid distance code' + db 0 + +ALIGN 4 +invalid_distance_too_far_msg: + db 'invalid distance too far back' + db 0 + + +ALIGN 4 +inflate_fast_mask: +dd 0 +dd 1 +dd 3 +dd 7 +dd 15 +dd 31 +dd 63 +dd 127 +dd 255 +dd 511 +dd 1023 +dd 2047 +dd 4095 +dd 8191 +dd 16383 +dd 32767 +dd 65535 +dd 131071 +dd 262143 +dd 524287 +dd 1048575 +dd 2097151 +dd 4194303 +dd 8388607 +dd 16777215 +dd 33554431 +dd 67108863 +dd 134217727 +dd 268435455 +dd 536870911 +dd 1073741823 +dd 2147483647 +dd 4294967295 + + +mode_state equ 0 ;/* state->mode */ +wsize_state equ (32+zlib1222sup) ;/* state->wsize */ +write_state equ (36+4+zlib1222sup) ;/* state->write */ +window_state equ (40+4+zlib1222sup) ;/* state->window */ +hold_state equ (44+4+zlib1222sup) ;/* state->hold */ +bits_state equ (48+4+zlib1222sup) ;/* state->bits */ +lencode_state equ (64+4+zlib1222sup) ;/* state->lencode */ +distcode_state equ (68+4+zlib1222sup) ;/* state->distcode */ +lenbits_state equ (72+4+zlib1222sup) ;/* state->lenbits */ +distbits_state equ (76+4+zlib1222sup) ;/* state->distbits */ + + +;;SECTION .text +; 205 "inffast.S" +;GLOBAL inflate_fast_use_mmx + +;SECTION .data + + +; GLOBAL inflate_fast_use_mmx:object +;.size inflate_fast_use_mmx, 4 +; 226 "inffast.S" +;SECTION .text + +ALIGN 4 +_inflate_fast proc near +.FPO (16, 4, 0, 0, 1, 0) + push edi + push esi + push ebp + push ebx + pushfd + sub esp,64 + cld + + + + + mov esi, [esp+88] + mov edi, [esi+28] + + + + + + + + mov edx, [esi+4] + mov eax, [esi+0] + + add edx,eax + sub edx,11 + + mov [esp+44],eax + mov [esp+20],edx + + mov ebp, [esp+92] + mov ecx, [esi+16] + mov ebx, [esi+12] + + sub ebp,ecx + neg ebp + add ebp,ebx + + sub ecx,257 + add ecx,ebx + + mov [esp+60],ebx + mov [esp+40],ebp + mov [esp+16],ecx +; 285 "inffast.S" + mov eax, [edi+lencode_state] + mov ecx, [edi+distcode_state] + + mov [esp+8],eax + mov [esp+12],ecx + + mov eax,1 + mov ecx, [edi+lenbits_state] + shl eax,cl + dec eax + mov [esp+0],eax + + mov eax,1 + mov ecx, [edi+distbits_state] + shl eax,cl + dec eax + mov [esp+4],eax + + mov eax, [edi+wsize_state] + mov ecx, [edi+write_state] + mov edx, [edi+window_state] + + mov [esp+52],eax + mov [esp+48],ecx + mov [esp+56],edx + + mov ebp, [edi+hold_state] + mov ebx, [edi+bits_state] +; 321 "inffast.S" + mov esi, [esp+44] + mov ecx, [esp+20] + cmp ecx,esi + ja L_align_long + + add ecx,11 + sub ecx,esi + mov eax,12 + sub eax,ecx + lea edi, [esp+28] + rep movsb + mov ecx,eax + xor eax,eax + rep stosb + lea esi, [esp+28] + mov [esp+20],esi + jmp L_is_aligned + + +L_align_long: + test esi,3 + jz L_is_aligned + xor eax,eax + mov al, [esi] + inc esi + mov ecx,ebx + add ebx,8 + shl eax,cl + or ebp,eax + jmp L_align_long + +L_is_aligned: + mov edi, [esp+60] +; 366 "inffast.S" +L_check_mmx: + cmp dword ptr [inflate_fast_use_mmx],2 + je L_init_mmx + ja L_do_loop + + push eax + push ebx + push ecx + push edx + pushfd + mov eax, [esp] + xor dword ptr [esp],0200000h + + + + + popfd + pushfd + pop edx + xor edx,eax + jz L_dont_use_mmx + xor eax,eax + cpuid + cmp ebx,0756e6547h + jne L_dont_use_mmx + cmp ecx,06c65746eh + jne L_dont_use_mmx + cmp edx,049656e69h + jne L_dont_use_mmx + mov eax,1 + cpuid + shr eax,8 + and eax,15 + cmp eax,6 + jne L_dont_use_mmx + test edx,0800000h + jnz L_use_mmx + jmp L_dont_use_mmx +L_use_mmx: + mov dword ptr [inflate_fast_use_mmx],2 + jmp L_check_mmx_pop +L_dont_use_mmx: + mov dword ptr [inflate_fast_use_mmx],3 +L_check_mmx_pop: + pop edx + pop ecx + pop ebx + pop eax + jmp L_check_mmx +; 426 "inffast.S" +ALIGN 4 +L_do_loop: +; 437 "inffast.S" + cmp bl,15 + ja L_get_length_code + + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + +L_get_length_code: + mov edx, [esp+0] + mov ecx, [esp+8] + and edx,ebp + mov eax, [ecx+edx*4] + +L_dolen: + + + + + + + mov cl,ah + sub bl,ah + shr ebp,cl + + + + + + + test al,al + jnz L_test_for_length_base + + shr eax,16 + stosb + +L_while_test: + + + cmp [esp+16],edi + jbe L_break_loop + + cmp [esp+20],esi + ja L_do_loop + jmp L_break_loop + +L_test_for_length_base: +; 502 "inffast.S" + mov edx,eax + shr edx,16 + mov cl,al + + test al,16 + jz L_test_for_second_level_length + and cl,15 + jz L_save_len + cmp bl,cl + jae L_add_bits_to_len + + mov ch,cl + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + mov cl,ch + +L_add_bits_to_len: + mov eax,1 + shl eax,cl + dec eax + sub bl,cl + and eax,ebp + shr ebp,cl + add edx,eax + +L_save_len: + mov [esp+24],edx + + +L_decode_distance: +; 549 "inffast.S" + cmp bl,15 + ja L_get_distance_code + + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + +L_get_distance_code: + mov edx, [esp+4] + mov ecx, [esp+12] + and edx,ebp + mov eax, [ecx+edx*4] + + +L_dodist: + mov edx,eax + shr edx,16 + mov cl,ah + sub bl,ah + shr ebp,cl +; 584 "inffast.S" + mov cl,al + + test al,16 + jz L_test_for_second_level_dist + and cl,15 + jz L_check_dist_one + cmp bl,cl + jae L_add_bits_to_dist + + mov ch,cl + xor eax,eax + lodsw + mov cl,bl + add bl,16 + shl eax,cl + or ebp,eax + mov cl,ch + +L_add_bits_to_dist: + mov eax,1 + shl eax,cl + dec eax + sub bl,cl + and eax,ebp + shr ebp,cl + add edx,eax + jmp L_check_window + +L_check_window: +; 625 "inffast.S" + mov [esp+44],esi + mov eax,edi + sub eax, [esp+40] + + cmp eax,edx + jb L_clip_window + + mov ecx, [esp+24] + mov esi,edi + sub esi,edx + + sub ecx,3 + mov al, [esi] + mov [edi],al + mov al, [esi+1] + mov dl, [esi+2] + add esi,3 + mov [edi+1],al + mov [edi+2],dl + add edi,3 + rep movsb + + mov esi, [esp+44] + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp edx,1 + jne L_check_window + cmp [esp+40],edi + je L_check_window + + dec edi + mov ecx, [esp+24] + mov al, [edi] + sub ecx,3 + + mov [edi+1],al + mov [edi+2],al + mov [edi+3],al + add edi,4 + rep stosb + + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + + + + + test al,64 + jnz L_test_for_end_of_block + + mov eax,1 + shl eax,cl + dec eax + and eax,ebp + add eax,edx + mov edx, [esp+8] + mov eax, [edx+eax*4] + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + + + + + test al,64 + jnz L_invalid_distance_code + + mov eax,1 + shl eax,cl + dec eax + and eax,ebp + add eax,edx + mov edx, [esp+12] + mov eax, [edx+eax*4] + jmp L_dodist + +ALIGN 4 +L_clip_window: +; 721 "inffast.S" + mov ecx,eax + mov eax, [esp+52] + neg ecx + mov esi, [esp+56] + + cmp eax,edx + jb L_invalid_distance_too_far + + add ecx,edx + cmp dword ptr [esp+48],0 + jne L_wrap_around_window + + sub eax,ecx + add esi,eax +; 749 "inffast.S" + mov eax, [esp+24] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + jmp L_do_copy1 + + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + jmp L_do_copy1 + +L_wrap_around_window: +; 793 "inffast.S" + mov eax, [esp+48] + cmp ecx,eax + jbe L_contiguous_in_window + + add esi, [esp+52] + add esi,eax + sub esi,ecx + sub ecx,eax + + + mov eax, [esp+24] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi, [esp+56] + mov ecx, [esp+48] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + jmp L_do_copy1 + +L_contiguous_in_window: +; 836 "inffast.S" + add esi,eax + sub esi,ecx + + + mov eax, [esp+24] + cmp eax,ecx + jbe L_do_copy1 + + sub eax,ecx + rep movsb + mov esi,edi + sub esi,edx + +L_do_copy1: +; 862 "inffast.S" + mov ecx,eax + rep movsb + + mov esi, [esp+44] + jmp L_while_test +; 878 "inffast.S" +ALIGN 4 +L_init_mmx: + emms + + + + + + movd mm0,ebp + mov ebp,ebx +; 896 "inffast.S" + movd mm4,dword ptr [esp+0] + movq mm3,mm4 + movd mm5,dword ptr [esp+4] + movq mm2,mm5 + pxor mm1,mm1 + mov ebx, [esp+8] + jmp L_do_loop_mmx + +ALIGN 4 +L_do_loop_mmx: + psrlq mm0,mm1 + + cmp ebp,32 + ja L_get_length_code_mmx + + movd mm6,ebp + movd mm7,dword ptr [esi] + add esi,4 + psllq mm7,mm6 + add ebp,32 + por mm0,mm7 + +L_get_length_code_mmx: + pand mm4,mm0 + movd eax,mm4 + movq mm4,mm3 + mov eax, [ebx+eax*4] + +L_dolen_mmx: + movzx ecx,ah + movd mm1,ecx + sub ebp,ecx + + test al,al + jnz L_test_for_length_base_mmx + + shr eax,16 + stosb + +L_while_test_mmx: + + + cmp [esp+16],edi + jbe L_break_loop + + cmp [esp+20],esi + ja L_do_loop_mmx + jmp L_break_loop + +L_test_for_length_base_mmx: + + mov edx,eax + shr edx,16 + + test al,16 + jz L_test_for_second_level_length_mmx + and eax,15 + jz L_decode_distance_mmx + + psrlq mm0,mm1 + movd mm1,eax + movd ecx,mm0 + sub ebp,eax + and ecx, [inflate_fast_mask+eax*4] + add edx,ecx + +L_decode_distance_mmx: + psrlq mm0,mm1 + + cmp ebp,32 + ja L_get_dist_code_mmx + + movd mm6,ebp + movd mm7,dword ptr [esi] + add esi,4 + psllq mm7,mm6 + add ebp,32 + por mm0,mm7 + +L_get_dist_code_mmx: + mov ebx, [esp+12] + pand mm5,mm0 + movd eax,mm5 + movq mm5,mm2 + mov eax, [ebx+eax*4] + +L_dodist_mmx: + + movzx ecx,ah + mov ebx,eax + shr ebx,16 + sub ebp,ecx + movd mm1,ecx + + test al,16 + jz L_test_for_second_level_dist_mmx + and eax,15 + jz L_check_dist_one_mmx + +L_add_bits_to_dist_mmx: + psrlq mm0,mm1 + movd mm1,eax + movd ecx,mm0 + sub ebp,eax + and ecx, [inflate_fast_mask+eax*4] + add ebx,ecx + +L_check_window_mmx: + mov [esp+44],esi + mov eax,edi + sub eax, [esp+40] + + cmp eax,ebx + jb L_clip_window_mmx + + mov ecx,edx + mov esi,edi + sub esi,ebx + + sub ecx,3 + mov al, [esi] + mov [edi],al + mov al, [esi+1] + mov dl, [esi+2] + add esi,3 + mov [edi+1],al + mov [edi+2],dl + add edi,3 + rep movsb + + mov esi, [esp+44] + mov ebx, [esp+8] + jmp L_while_test_mmx + +ALIGN 4 +L_check_dist_one_mmx: + cmp ebx,1 + jne L_check_window_mmx + cmp [esp+40],edi + je L_check_window_mmx + + dec edi + mov ecx,edx + mov al, [edi] + sub ecx,3 + + mov [edi+1],al + mov [edi+2],al + mov [edi+3],al + add edi,4 + rep stosb + + mov ebx, [esp+8] + jmp L_while_test_mmx + +ALIGN 4 +L_test_for_second_level_length_mmx: + test al,64 + jnz L_test_for_end_of_block + + and eax,15 + psrlq mm0,mm1 + movd ecx,mm0 + and ecx, [inflate_fast_mask+eax*4] + add ecx,edx + mov eax, [ebx+ecx*4] + jmp L_dolen_mmx + +ALIGN 4 +L_test_for_second_level_dist_mmx: + test al,64 + jnz L_invalid_distance_code + + and eax,15 + psrlq mm0,mm1 + movd ecx,mm0 + and ecx, [inflate_fast_mask+eax*4] + mov eax, [esp+12] + add ecx,ebx + mov eax, [eax+ecx*4] + jmp L_dodist_mmx + +ALIGN 4 +L_clip_window_mmx: + + mov ecx,eax + mov eax, [esp+52] + neg ecx + mov esi, [esp+56] + + cmp eax,ebx + jb L_invalid_distance_too_far + + add ecx,ebx + cmp dword ptr [esp+48],0 + jne L_wrap_around_window_mmx + + sub eax,ecx + add esi,eax + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + jmp L_do_copy1_mmx + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + jmp L_do_copy1_mmx + +L_wrap_around_window_mmx: + + mov eax, [esp+48] + cmp ecx,eax + jbe L_contiguous_in_window_mmx + + add esi, [esp+52] + add esi,eax + sub esi,ecx + sub ecx,eax + + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi, [esp+56] + mov ecx, [esp+48] + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + jmp L_do_copy1_mmx + +L_contiguous_in_window_mmx: + + add esi,eax + sub esi,ecx + + + cmp edx,ecx + jbe L_do_copy1_mmx + + sub edx,ecx + rep movsb + mov esi,edi + sub esi,ebx + +L_do_copy1_mmx: + + + mov ecx,edx + rep movsb + + mov esi, [esp+44] + mov ebx, [esp+8] + jmp L_while_test_mmx +; 1174 "inffast.S" +L_invalid_distance_code: + + + + + + mov ecx, invalid_distance_code_msg + mov edx,INFLATE_MODE_BAD + jmp L_update_stream_state + +L_test_for_end_of_block: + + + + + + test al,32 + jz L_invalid_literal_length_code + + mov ecx,0 + mov edx,INFLATE_MODE_TYPE + jmp L_update_stream_state + +L_invalid_literal_length_code: + + + + + + mov ecx, invalid_literal_length_code_msg + mov edx,INFLATE_MODE_BAD + jmp L_update_stream_state + +L_invalid_distance_too_far: + + + + mov esi, [esp+44] + mov ecx, invalid_distance_too_far_msg + mov edx,INFLATE_MODE_BAD + jmp L_update_stream_state + +L_update_stream_state: + + mov eax, [esp+88] + test ecx,ecx + jz L_skip_msg + mov [eax+24],ecx +L_skip_msg: + mov eax, [eax+28] + mov [eax+mode_state],edx + jmp L_break_loop + +ALIGN 4 +L_break_loop: +; 1243 "inffast.S" + cmp dword ptr [inflate_fast_use_mmx],2 + jne L_update_next_in + + + + mov ebx,ebp + +L_update_next_in: +; 1266 "inffast.S" + mov eax, [esp+88] + mov ecx,ebx + mov edx, [eax+28] + shr ecx,3 + sub esi,ecx + shl ecx,3 + sub ebx,ecx + mov [eax+12],edi + mov [edx+bits_state],ebx + mov ecx,ebx + + lea ebx, [esp+28] + cmp [esp+20],ebx + jne L_buf_not_used + + sub esi,ebx + mov ebx, [eax+0] + mov [esp+20],ebx + add esi,ebx + mov ebx, [eax+4] + sub ebx,11 + add [esp+20],ebx + +L_buf_not_used: + mov [eax+0],esi + + mov ebx,1 + shl ebx,cl + dec ebx + + + + + + cmp dword ptr [inflate_fast_use_mmx],2 + jne L_update_hold + + + + psrlq mm0,mm1 + movd ebp,mm0 + + emms + +L_update_hold: + + + + and ebp,ebx + mov [edx+hold_state],ebp + + + + + mov ebx, [esp+20] + cmp ebx,esi + jbe L_last_is_smaller + + sub ebx,esi + add ebx,11 + mov [eax+4],ebx + jmp L_fixup_out +L_last_is_smaller: + sub esi,ebx + neg esi + add esi,11 + mov [eax+4],esi + + + + +L_fixup_out: + + mov ebx, [esp+16] + cmp ebx,edi + jbe L_end_is_smaller + + sub ebx,edi + add ebx,257 + mov [eax+16],ebx + jmp L_done +L_end_is_smaller: + sub edi,ebx + neg edi + add edi,257 + mov [eax+16],edi + + + + + +L_done: + add esp,64 + popfd + pop ebx + pop ebp + pop esi + pop edi + ret +_inflate_fast endp + +_TEXT ends +end diff --git a/libz/contrib/masmx86/inffas32.lst b/libz/contrib/masmx86/inffas32.lst new file mode 100644 index 000000000..9c6137479 --- /dev/null +++ b/libz/contrib/masmx86/inffas32.lst @@ -0,0 +1,1224 @@ +Microsoft (R) Macro Assembler Version 12.00.31101.0 05/22/17 22:38:56 +inffas32.asm Page 1 - 1 + + + ;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding + ; * + ; * inffas32.asm is derivated from inffas86.c, with translation of assembly code + ; * + ; * Copyright (C) 1995-2003 Mark Adler + ; * For conditions of distribution and use, see copyright notice in zlib.h + ; * + ; * Copyright (C) 2003 Chris Anderson + ; * Please use the copyright conditions above. + ; * + ; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from + ; * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at + ; * the moment. I have successfully compiled and tested this code with gcc2.96, + ; * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S + ; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX + ; * enabled. I will attempt to merge the MMX code into this version. Newer + ; * versions of this and inffast.S can be found at + ; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ + ; * + ; * 2005 : modification by Gilles Vollant + ; */ + ; For Visual C++ 4.x and higher and ML 6.x and higher + ; ml.exe is in directory \MASM611C of Win95 DDK + ; ml.exe is also distributed in http://www.masm32.com/masmdl.htm + ; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/ + ; + ; + ; compile with command line option + ; ml /coff /Zi /c /Flinffas32.lst inffas32.asm + + ; if you define NO_GZIP (see inflate.h), compile with + ; ml /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm + + + ; zlib122sup is 0 fort zlib 1.2.2.1 and lower + ; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head + ; in inflate_state in inflate.h) + = 00000008 zlib1222sup equ 8 + + + IFDEF GUNZIP + ELSE + IFNDEF NO_GUNZIP + = 0000000B INFLATE_MODE_TYPE equ 11 + = 0000001A INFLATE_MODE_BAD equ 26 + ELSE + ENDIF + ENDIF + + + ; 75 "inffast.S" + ;FILE "inffast.S" + + ;;;GLOBAL _inflate_fast + + ;;;SECTION .text + + + + .586p + .mmx + + name inflate_fast_x86 + .MODEL FLAT + + 00000000 _DATA segment + 00000000 inflate_fast_use_mmx: + 00000000 00000001 dd 1 + + + 00000000 _TEXT segment + + + + ALIGN 4 + 00000000 46 61 73 74 20 db 'Fast decoding Code from Chris Anderson' + 64 65 63 6F 64 + 69 6E 67 20 43 + 6F 64 65 20 66 + 72 6F 6D 20 43 + 68 72 69 73 20 + 41 6E 64 65 72 + 73 6F 6E + 00000026 00 db 0 + + ALIGN 4 + 00000028 invalid_literal_length_code_msg: + 00000028 69 6E 76 61 6C db 'invalid literal/length code' + 69 64 20 6C 69 + 74 65 72 61 6C + 2F 6C 65 6E 67 + 74 68 20 63 6F + 64 65 + 00000043 00 db 0 + + ALIGN 4 + 00000044 invalid_distance_code_msg: + 00000044 69 6E 76 61 6C db 'invalid distance code' + 69 64 20 64 69 + 73 74 61 6E 63 + 65 20 63 6F 64 + 65 + 00000059 00 db 0 + + ALIGN 4 + 0000005C invalid_distance_too_far_msg: + 0000005C 69 6E 76 61 6C db 'invalid distance too far back' + 69 64 20 64 69 + 73 74 61 6E 63 + 65 20 74 6F 6F + 20 66 61 72 20 + 62 61 63 6B + 00000079 00 db 0 + + + ALIGN 4 + 0000007C inflate_fast_mask: + 0000007C 00000000 dd 0 + 00000080 00000001 dd 1 + 00000084 00000003 dd 3 + 00000088 00000007 dd 7 + 0000008C 0000000F dd 15 + 00000090 0000001F dd 31 + 00000094 0000003F dd 63 + 00000098 0000007F dd 127 + 0000009C 000000FF dd 255 + 000000A0 000001FF dd 511 + 000000A4 000003FF dd 1023 + 000000A8 000007FF dd 2047 + 000000AC 00000FFF dd 4095 + 000000B0 00001FFF dd 8191 + 000000B4 00003FFF dd 16383 + 000000B8 00007FFF dd 32767 + 000000BC 0000FFFF dd 65535 + 000000C0 0001FFFF dd 131071 + 000000C4 0003FFFF dd 262143 + 000000C8 0007FFFF dd 524287 + 000000CC 000FFFFF dd 1048575 + 000000D0 001FFFFF dd 2097151 + 000000D4 003FFFFF dd 4194303 + 000000D8 007FFFFF dd 8388607 + 000000DC 00FFFFFF dd 16777215 + 000000E0 01FFFFFF dd 33554431 + 000000E4 03FFFFFF dd 67108863 + 000000E8 07FFFFFF dd 134217727 + 000000EC 0FFFFFFF dd 268435455 + 000000F0 1FFFFFFF dd 536870911 + 000000F4 3FFFFFFF dd 1073741823 + 000000F8 7FFFFFFF dd 2147483647 + 000000FC FFFFFFFF dd 4294967295 + + + = 00000000 mode_state equ 0 ;/* state->mode */ + = 00000028 wsize_state equ (32+zlib1222sup) ;/* state->wsize */ + = 00000030 write_state equ (36+4+zlib1222sup) ;/* state->write */ + = 00000034 window_state equ (40+4+zlib1222sup) ;/* state->window */ + = 00000038 hold_state equ (44+4+zlib1222sup) ;/* state->hold */ + = 0000003C bits_state equ (48+4+zlib1222sup) ;/* state->bits */ + = 0000004C lencode_state equ (64+4+zlib1222sup) ;/* state->lencode */ + = 00000050 distcode_state equ (68+4+zlib1222sup) ;/* state->distcode */ + = 00000054 lenbits_state equ (72+4+zlib1222sup) ;/* state->lenbits */ + = 00000058 distbits_state equ (76+4+zlib1222sup) ;/* state->distbits */ + + + ;;SECTION .text + ; 205 "inffast.S" + ;GLOBAL inflate_fast_use_mmx + + ;SECTION .data + + + ; GLOBAL inflate_fast_use_mmx:object + ;.size inflate_fast_use_mmx, 4 + ; 226 "inffast.S" + ;SECTION .text + + ALIGN 4 + 00000100 _inflate_fast proc near + 00000100 .FPO (16, 4, 0, 0, 1, 0) + 00000100 57 push edi + 00000101 56 push esi + 00000102 55 push ebp + 00000103 53 push ebx + 00000104 9C pushfd + 00000105 83 EC 40 sub esp,64 + 00000108 FC cld + + + + + 00000109 8B 74 24 58 mov esi, [esp+88] + 0000010D 8B 7E 1C mov edi, [esi+28] + + + + + + + + 00000110 8B 56 04 mov edx, [esi+4] + 00000113 8B 06 mov eax, [esi+0] + + 00000115 03 D0 add edx,eax + 00000117 83 EA 0B sub edx,11 + + 0000011A 89 44 24 2C mov [esp+44],eax + 0000011E 89 54 24 14 mov [esp+20],edx + + 00000122 8B 6C 24 5C mov ebp, [esp+92] + 00000126 8B 4E 10 mov ecx, [esi+16] + 00000129 8B 5E 0C mov ebx, [esi+12] + + 0000012C 2B E9 sub ebp,ecx + 0000012E F7 DD neg ebp + 00000130 03 EB add ebp,ebx + + 00000132 81 E9 00000101 sub ecx,257 + 00000138 03 CB add ecx,ebx + + 0000013A 89 5C 24 3C mov [esp+60],ebx + 0000013E 89 6C 24 28 mov [esp+40],ebp + 00000142 89 4C 24 10 mov [esp+16],ecx + ; 285 "inffast.S" + 00000146 8B 47 4C mov eax, [edi+lencode_state] + 00000149 8B 4F 50 mov ecx, [edi+distcode_state] + + 0000014C 89 44 24 08 mov [esp+8],eax + 00000150 89 4C 24 0C mov [esp+12],ecx + + 00000154 B8 00000001 mov eax,1 + 00000159 8B 4F 54 mov ecx, [edi+lenbits_state] + 0000015C D3 E0 shl eax,cl + 0000015E 48 dec eax + 0000015F 89 04 24 mov [esp+0],eax + + 00000162 B8 00000001 mov eax,1 + 00000167 8B 4F 58 mov ecx, [edi+distbits_state] + 0000016A D3 E0 shl eax,cl + 0000016C 48 dec eax + 0000016D 89 44 24 04 mov [esp+4],eax + + 00000171 8B 47 28 mov eax, [edi+wsize_state] + 00000174 8B 4F 30 mov ecx, [edi+write_state] + 00000177 8B 57 34 mov edx, [edi+window_state] + + 0000017A 89 44 24 34 mov [esp+52],eax + 0000017E 89 4C 24 30 mov [esp+48],ecx + 00000182 89 54 24 38 mov [esp+56],edx + + 00000186 8B 6F 38 mov ebp, [edi+hold_state] + 00000189 8B 5F 3C mov ebx, [edi+bits_state] + ; 321 "inffast.S" + 0000018C 8B 74 24 2C mov esi, [esp+44] + 00000190 8B 4C 24 14 mov ecx, [esp+20] + 00000194 3B CE cmp ecx,esi + 00000196 77 22 ja L_align_long + + 00000198 83 C1 0B add ecx,11 + 0000019B 2B CE sub ecx,esi + 0000019D B8 0000000C mov eax,12 + 000001A2 2B C1 sub eax,ecx + 000001A4 8D 7C 24 1C lea edi, [esp+28] + 000001A8 F3/ A4 rep movsb + 000001AA 8B C8 mov ecx,eax + 000001AC 33 C0 xor eax,eax + 000001AE F3/ AA rep stosb + 000001B0 8D 74 24 1C lea esi, [esp+28] + 000001B4 89 74 24 14 mov [esp+20],esi + 000001B8 EB 18 jmp L_is_aligned + + + 000001BA L_align_long: + 000001BA F7 C6 00000003 test esi,3 + 000001C0 74 10 jz L_is_aligned + 000001C2 33 C0 xor eax,eax + 000001C4 8A 06 mov al, [esi] + 000001C6 46 inc esi + 000001C7 8B CB mov ecx,ebx + 000001C9 83 C3 08 add ebx,8 + 000001CC D3 E0 shl eax,cl + 000001CE 0B E8 or ebp,eax + 000001D0 EB E8 jmp L_align_long + + 000001D2 L_is_aligned: + 000001D2 8B 7C 24 3C mov edi, [esp+60] + ; 366 "inffast.S" + 000001D6 L_check_mmx: + 000001D6 83 3D 00000000 R cmp dword ptr [inflate_fast_use_mmx],2 + 02 + 000001DD 0F 84 00000289 je L_init_mmx + 000001E3 77 6B ja L_do_loop + + 000001E5 50 push eax + 000001E6 53 push ebx + 000001E7 51 push ecx + 000001E8 52 push edx + 000001E9 9C pushfd + 000001EA 8B 04 24 mov eax, [esp] + 000001ED 81 34 24 xor dword ptr [esp],0200000h + 00200000 + + + + + 000001F4 9D popfd + 000001F5 9C pushfd + 000001F6 5A pop edx + 000001F7 33 D0 xor edx,eax + 000001F9 74 44 jz L_dont_use_mmx + 000001FB 33 C0 xor eax,eax + 000001FD 0F A2 cpuid + 000001FF 81 FB 756E6547 cmp ebx,0756e6547h + 00000205 75 38 jne L_dont_use_mmx + 00000207 81 F9 6C65746E cmp ecx,06c65746eh + 0000020D 75 30 jne L_dont_use_mmx + 0000020F 81 FA 49656E69 cmp edx,049656e69h + 00000215 75 28 jne L_dont_use_mmx + 00000217 B8 00000001 mov eax,1 + 0000021C 0F A2 cpuid + 0000021E C1 E8 08 shr eax,8 + 00000221 83 E0 0F and eax,15 + 00000224 83 F8 06 cmp eax,6 + 00000227 75 16 jne L_dont_use_mmx + 00000229 F7 C2 00800000 test edx,0800000h + 0000022F 75 02 jnz L_use_mmx + 00000231 EB 0C jmp L_dont_use_mmx + 00000233 L_use_mmx: + 00000233 C7 05 00000000 R mov dword ptr [inflate_fast_use_mmx],2 + 00000002 + 0000023D EB 0A jmp L_check_mmx_pop + 0000023F L_dont_use_mmx: + 0000023F C7 05 00000000 R mov dword ptr [inflate_fast_use_mmx],3 + 00000003 + 00000249 L_check_mmx_pop: + 00000249 5A pop edx + 0000024A 59 pop ecx + 0000024B 5B pop ebx + 0000024C 58 pop eax + 0000024D EB 87 jmp L_check_mmx + ; 426 "inffast.S" + ALIGN 4 + 00000250 L_do_loop: + ; 437 "inffast.S" + 00000250 80 FB 0F cmp bl,15 + 00000253 77 0D ja L_get_length_code + + 00000255 33 C0 xor eax,eax + 00000257 66| AD lodsw + 00000259 8A CB mov cl,bl + 0000025B 80 C3 10 add bl,16 + 0000025E D3 E0 shl eax,cl + 00000260 0B E8 or ebp,eax + + 00000262 L_get_length_code: + 00000262 8B 14 24 mov edx, [esp+0] + 00000265 8B 4C 24 08 mov ecx, [esp+8] + 00000269 23 D5 and edx,ebp + 0000026B 8B 04 91 mov eax, [ecx+edx*4] + + 0000026E L_dolen: + + + + + + + 0000026E 8A CC mov cl,ah + 00000270 2A DC sub bl,ah + 00000272 D3 ED shr ebp,cl + + + + + + + 00000274 84 C0 test al,al + 00000276 75 19 jnz L_test_for_length_base + + 00000278 C1 E8 10 shr eax,16 + 0000027B AA stosb + + 0000027C L_while_test: + + + 0000027C 39 7C 24 10 cmp [esp+16],edi + 00000280 0F 86 00000462 jbe L_break_loop + + 00000286 39 74 24 14 cmp [esp+20],esi + 0000028A 77 C4 ja L_do_loop + 0000028C E9 00000457 jmp L_break_loop + + 00000291 L_test_for_length_base: + ; 502 "inffast.S" + 00000291 8B D0 mov edx,eax + 00000293 C1 EA 10 shr edx,16 + 00000296 8A C8 mov cl,al + + 00000298 A8 10 test al,16 + 0000029A 0F 84 000000F4 jz L_test_for_second_level_length + 000002A0 80 E1 0F and cl,15 + 000002A3 74 25 jz L_save_len + 000002A5 3A D9 cmp bl,cl + 000002A7 73 11 jae L_add_bits_to_len + + 000002A9 8A E9 mov ch,cl + 000002AB 33 C0 xor eax,eax + 000002AD 66| AD lodsw + 000002AF 8A CB mov cl,bl + 000002B1 80 C3 10 add bl,16 + 000002B4 D3 E0 shl eax,cl + 000002B6 0B E8 or ebp,eax + 000002B8 8A CD mov cl,ch + + 000002BA L_add_bits_to_len: + 000002BA B8 00000001 mov eax,1 + 000002BF D3 E0 shl eax,cl + 000002C1 48 dec eax + 000002C2 2A D9 sub bl,cl + 000002C4 23 C5 and eax,ebp + 000002C6 D3 ED shr ebp,cl + 000002C8 03 D0 add edx,eax + + 000002CA L_save_len: + 000002CA 89 54 24 18 mov [esp+24],edx + + + 000002CE L_decode_distance: + ; 549 "inffast.S" + 000002CE 80 FB 0F cmp bl,15 + 000002D1 77 0D ja L_get_distance_code + + 000002D3 33 C0 xor eax,eax + 000002D5 66| AD lodsw + 000002D7 8A CB mov cl,bl + 000002D9 80 C3 10 add bl,16 + 000002DC D3 E0 shl eax,cl + 000002DE 0B E8 or ebp,eax + + 000002E0 L_get_distance_code: + 000002E0 8B 54 24 04 mov edx, [esp+4] + 000002E4 8B 4C 24 0C mov ecx, [esp+12] + 000002E8 23 D5 and edx,ebp + 000002EA 8B 04 91 mov eax, [ecx+edx*4] + + + 000002ED L_dodist: + 000002ED 8B D0 mov edx,eax + 000002EF C1 EA 10 shr edx,16 + 000002F2 8A CC mov cl,ah + 000002F4 2A DC sub bl,ah + 000002F6 D3 ED shr ebp,cl + ; 584 "inffast.S" + 000002F8 8A C8 mov cl,al + + 000002FA A8 10 test al,16 + 000002FC 0F 84 000000B2 jz L_test_for_second_level_dist + 00000302 80 E1 0F and cl,15 + 00000305 74 65 jz L_check_dist_one + 00000307 3A D9 cmp bl,cl + 00000309 73 11 jae L_add_bits_to_dist + + 0000030B 8A E9 mov ch,cl + 0000030D 33 C0 xor eax,eax + 0000030F 66| AD lodsw + 00000311 8A CB mov cl,bl + 00000313 80 C3 10 add bl,16 + 00000316 D3 E0 shl eax,cl + 00000318 0B E8 or ebp,eax + 0000031A 8A CD mov cl,ch + + 0000031C L_add_bits_to_dist: + 0000031C B8 00000001 mov eax,1 + 00000321 D3 E0 shl eax,cl + 00000323 48 dec eax + 00000324 2A D9 sub bl,cl + 00000326 23 C5 and eax,ebp + 00000328 D3 ED shr ebp,cl + 0000032A 03 D0 add edx,eax + 0000032C EB 00 jmp L_check_window + + 0000032E L_check_window: + ; 625 "inffast.S" + 0000032E 89 74 24 2C mov [esp+44],esi + 00000332 8B C7 mov eax,edi + 00000334 2B 44 24 28 sub eax, [esp+40] + + 00000338 3B C2 cmp eax,edx + 0000033A 0F 82 00000094 jb L_clip_window + + 00000340 8B 4C 24 18 mov ecx, [esp+24] + 00000344 8B F7 mov esi,edi + 00000346 2B F2 sub esi,edx + + 00000348 83 E9 03 sub ecx,3 + 0000034B 8A 06 mov al, [esi] + 0000034D 88 07 mov [edi],al + 0000034F 8A 46 01 mov al, [esi+1] + 00000352 8A 56 02 mov dl, [esi+2] + 00000355 83 C6 03 add esi,3 + 00000358 88 47 01 mov [edi+1],al + 0000035B 88 57 02 mov [edi+2],dl + 0000035E 83 C7 03 add edi,3 + 00000361 F3/ A4 rep movsb + + 00000363 8B 74 24 2C mov esi, [esp+44] + 00000367 E9 FFFFFF10 jmp L_while_test + + ALIGN 4 + 0000036C L_check_dist_one: + 0000036C 83 FA 01 cmp edx,1 + 0000036F 75 BD jne L_check_window + 00000371 39 7C 24 28 cmp [esp+40],edi + 00000375 74 B7 je L_check_window + + 00000377 4F dec edi + 00000378 8B 4C 24 18 mov ecx, [esp+24] + 0000037C 8A 07 mov al, [edi] + 0000037E 83 E9 03 sub ecx,3 + + 00000381 88 47 01 mov [edi+1],al + 00000384 88 47 02 mov [edi+2],al + 00000387 88 47 03 mov [edi+3],al + 0000038A 83 C7 04 add edi,4 + 0000038D F3/ AA rep stosb + + 0000038F E9 FFFFFEE8 jmp L_while_test + + ALIGN 4 + 00000394 L_test_for_second_level_length: + + + + + 00000394 A8 40 test al,64 + 00000396 0F 85 0000030E jnz L_test_for_end_of_block + + 0000039C B8 00000001 mov eax,1 + 000003A1 D3 E0 shl eax,cl + 000003A3 48 dec eax + 000003A4 23 C5 and eax,ebp + 000003A6 03 C2 add eax,edx + 000003A8 8B 54 24 08 mov edx, [esp+8] + 000003AC 8B 04 82 mov eax, [edx+eax*4] + 000003AF E9 FFFFFEBA jmp L_dolen + + ALIGN 4 + 000003B4 L_test_for_second_level_dist: + + + + + 000003B4 A8 40 test al,64 + 000003B6 0F 85 000002E2 jnz L_invalid_distance_code + + 000003BC B8 00000001 mov eax,1 + 000003C1 D3 E0 shl eax,cl + 000003C3 48 dec eax + 000003C4 23 C5 and eax,ebp + 000003C6 03 C2 add eax,edx + 000003C8 8B 54 24 0C mov edx, [esp+12] + 000003CC 8B 04 82 mov eax, [edx+eax*4] + 000003CF E9 FFFFFF19 jmp L_dodist + + ALIGN 4 + 000003D4 L_clip_window: + ; 721 "inffast.S" + 000003D4 8B C8 mov ecx,eax + 000003D6 8B 44 24 34 mov eax, [esp+52] + 000003DA F7 D9 neg ecx + 000003DC 8B 74 24 38 mov esi, [esp+56] + + 000003E0 3B C2 cmp eax,edx + 000003E2 0F 82 000002DE jb L_invalid_distance_too_far + + 000003E8 03 CA add ecx,edx + 000003EA 83 7C 24 30 00 cmp dword ptr [esp+48],0 + 000003EF 75 24 jne L_wrap_around_window + + 000003F1 2B C1 sub eax,ecx + 000003F3 03 F0 add esi,eax + ; 749 "inffast.S" + 000003F5 8B 44 24 18 mov eax, [esp+24] + 000003F9 3B C1 cmp eax,ecx + 000003FB 76 60 jbe L_do_copy1 + + 000003FD 2B C1 sub eax,ecx + 000003FF F3/ A4 rep movsb + 00000401 8B F7 mov esi,edi + 00000403 2B F2 sub esi,edx + 00000405 EB 56 jmp L_do_copy1 + + 00000407 3B C1 cmp eax,ecx + 00000409 76 52 jbe L_do_copy1 + + 0000040B 2B C1 sub eax,ecx + 0000040D F3/ A4 rep movsb + 0000040F 8B F7 mov esi,edi + 00000411 2B F2 sub esi,edx + 00000413 EB 48 jmp L_do_copy1 + + 00000415 L_wrap_around_window: + ; 793 "inffast.S" + 00000415 8B 44 24 30 mov eax, [esp+48] + 00000419 3B C8 cmp ecx,eax + 0000041B 76 2C jbe L_contiguous_in_window + + 0000041D 03 74 24 34 add esi, [esp+52] + 00000421 03 F0 add esi,eax + 00000423 2B F1 sub esi,ecx + 00000425 2B C8 sub ecx,eax + + + 00000427 8B 44 24 18 mov eax, [esp+24] + 0000042B 3B C1 cmp eax,ecx + 0000042D 76 2E jbe L_do_copy1 + + 0000042F 2B C1 sub eax,ecx + 00000431 F3/ A4 rep movsb + 00000433 8B 74 24 38 mov esi, [esp+56] + 00000437 8B 4C 24 30 mov ecx, [esp+48] + 0000043B 3B C1 cmp eax,ecx + 0000043D 76 1E jbe L_do_copy1 + + 0000043F 2B C1 sub eax,ecx + 00000441 F3/ A4 rep movsb + 00000443 8B F7 mov esi,edi + 00000445 2B F2 sub esi,edx + 00000447 EB 14 jmp L_do_copy1 + + 00000449 L_contiguous_in_window: + ; 836 "inffast.S" + 00000449 03 F0 add esi,eax + 0000044B 2B F1 sub esi,ecx + + + 0000044D 8B 44 24 18 mov eax, [esp+24] + 00000451 3B C1 cmp eax,ecx + 00000453 76 08 jbe L_do_copy1 + + 00000455 2B C1 sub eax,ecx + 00000457 F3/ A4 rep movsb + 00000459 8B F7 mov esi,edi + 0000045B 2B F2 sub esi,edx + + 0000045D L_do_copy1: + ; 862 "inffast.S" + 0000045D 8B C8 mov ecx,eax + 0000045F F3/ A4 rep movsb + + 00000461 8B 74 24 2C mov esi, [esp+44] + 00000465 E9 FFFFFE12 jmp L_while_test + ; 878 "inffast.S" + ALIGN 4 + 0000046C L_init_mmx: + 0000046C 0F 77 emms + + + + + + 0000046E 0F 6E C5 movd mm0,ebp + 00000471 8B EB mov ebp,ebx + ; 896 "inffast.S" + 00000473 0F 6E 24 24 movd mm4,dword ptr [esp+0] + 00000477 0F 7F E3 movq mm3,mm4 + 0000047A 0F 6E 6C 24 04 movd mm5,dword ptr [esp+4] + 0000047F 0F 7F EA movq mm2,mm5 + 00000482 0F EF C9 pxor mm1,mm1 + 00000485 8B 5C 24 08 mov ebx, [esp+8] + 00000489 EB 01 jmp L_do_loop_mmx + + ALIGN 4 + 0000048C L_do_loop_mmx: + 0000048C 0F D3 C1 psrlq mm0,mm1 + + 0000048F 83 FD 20 cmp ebp,32 + 00000492 77 12 ja L_get_length_code_mmx + + 00000494 0F 6E F5 movd mm6,ebp + 00000497 0F 6E 3E movd mm7,dword ptr [esi] + 0000049A 83 C6 04 add esi,4 + 0000049D 0F F3 FE psllq mm7,mm6 + 000004A0 83 C5 20 add ebp,32 + 000004A3 0F EB C7 por mm0,mm7 + + 000004A6 L_get_length_code_mmx: + 000004A6 0F DB E0 pand mm4,mm0 + 000004A9 0F 7E E0 movd eax,mm4 + 000004AC 0F 7F DC movq mm4,mm3 + 000004AF 8B 04 83 mov eax, [ebx+eax*4] + + 000004B2 L_dolen_mmx: + 000004B2 0F B6 CC movzx ecx,ah + 000004B5 0F 6E C9 movd mm1,ecx + 000004B8 2B E9 sub ebp,ecx + + 000004BA 84 C0 test al,al + 000004BC 75 19 jnz L_test_for_length_base_mmx + + 000004BE C1 E8 10 shr eax,16 + 000004C1 AA stosb + + 000004C2 L_while_test_mmx: + + + 000004C2 39 7C 24 10 cmp [esp+16],edi + 000004C6 0F 86 0000021C jbe L_break_loop + + 000004CC 39 74 24 14 cmp [esp+20],esi + 000004D0 77 BA ja L_do_loop_mmx + 000004D2 E9 00000211 jmp L_break_loop + + 000004D7 L_test_for_length_base_mmx: + + 000004D7 8B D0 mov edx,eax + 000004D9 C1 EA 10 shr edx,16 + + 000004DC A8 10 test al,16 + 000004DE 0F 84 000000E0 jz L_test_for_second_level_length_mmx + 000004E4 83 E0 0F and eax,15 + 000004E7 74 14 jz L_decode_distance_mmx + + 000004E9 0F D3 C1 psrlq mm0,mm1 + 000004EC 0F 6E C8 movd mm1,eax + 000004EF 0F 7E C1 movd ecx,mm0 + 000004F2 2B E8 sub ebp,eax + 000004F4 23 0C 85 and ecx, [inflate_fast_mask+eax*4] + 0000007C R + 000004FB 03 D1 add edx,ecx + + 000004FD L_decode_distance_mmx: + 000004FD 0F D3 C1 psrlq mm0,mm1 + + 00000500 83 FD 20 cmp ebp,32 + 00000503 77 12 ja L_get_dist_code_mmx + + 00000505 0F 6E F5 movd mm6,ebp + 00000508 0F 6E 3E movd mm7,dword ptr [esi] + 0000050B 83 C6 04 add esi,4 + 0000050E 0F F3 FE psllq mm7,mm6 + 00000511 83 C5 20 add ebp,32 + 00000514 0F EB C7 por mm0,mm7 + + 00000517 L_get_dist_code_mmx: + 00000517 8B 5C 24 0C mov ebx, [esp+12] + 0000051B 0F DB E8 pand mm5,mm0 + 0000051E 0F 7E E8 movd eax,mm5 + 00000521 0F 7F D5 movq mm5,mm2 + 00000524 8B 04 83 mov eax, [ebx+eax*4] + + 00000527 L_dodist_mmx: + + 00000527 0F B6 CC movzx ecx,ah + 0000052A 8B D8 mov ebx,eax + 0000052C C1 EB 10 shr ebx,16 + 0000052F 2B E9 sub ebp,ecx + 00000531 0F 6E C9 movd mm1,ecx + + 00000534 A8 10 test al,16 + 00000536 0F 84 000000AC jz L_test_for_second_level_dist_mmx + 0000053C 83 E0 0F and eax,15 + 0000053F 74 57 jz L_check_dist_one_mmx + + 00000541 L_add_bits_to_dist_mmx: + 00000541 0F D3 C1 psrlq mm0,mm1 + 00000544 0F 6E C8 movd mm1,eax + 00000547 0F 7E C1 movd ecx,mm0 + 0000054A 2B E8 sub ebp,eax + 0000054C 23 0C 85 and ecx, [inflate_fast_mask+eax*4] + 0000007C R + 00000553 03 D9 add ebx,ecx + + 00000555 L_check_window_mmx: + 00000555 89 74 24 2C mov [esp+44],esi + 00000559 8B C7 mov eax,edi + 0000055B 2B 44 24 28 sub eax, [esp+40] + + 0000055F 3B C3 cmp eax,ebx + 00000561 0F 82 000000A9 jb L_clip_window_mmx + + 00000567 8B CA mov ecx,edx + 00000569 8B F7 mov esi,edi + 0000056B 2B F3 sub esi,ebx + + 0000056D 83 E9 03 sub ecx,3 + 00000570 8A 06 mov al, [esi] + 00000572 88 07 mov [edi],al + 00000574 8A 46 01 mov al, [esi+1] + 00000577 8A 56 02 mov dl, [esi+2] + 0000057A 83 C6 03 add esi,3 + 0000057D 88 47 01 mov [edi+1],al + 00000580 88 57 02 mov [edi+2],dl + 00000583 83 C7 03 add edi,3 + 00000586 F3/ A4 rep movsb + + 00000588 8B 74 24 2C mov esi, [esp+44] + 0000058C 8B 5C 24 08 mov ebx, [esp+8] + 00000590 E9 FFFFFF2D jmp L_while_test_mmx + + ALIGN 4 + 00000598 L_check_dist_one_mmx: + 00000598 83 FB 01 cmp ebx,1 + 0000059B 75 B8 jne L_check_window_mmx + 0000059D 39 7C 24 28 cmp [esp+40],edi + 000005A1 74 B2 je L_check_window_mmx + + 000005A3 4F dec edi + 000005A4 8B CA mov ecx,edx + 000005A6 8A 07 mov al, [edi] + 000005A8 83 E9 03 sub ecx,3 + + 000005AB 88 47 01 mov [edi+1],al + 000005AE 88 47 02 mov [edi+2],al + 000005B1 88 47 03 mov [edi+3],al + 000005B4 83 C7 04 add edi,4 + 000005B7 F3/ AA rep stosb + + 000005B9 8B 5C 24 08 mov ebx, [esp+8] + 000005BD E9 FFFFFF00 jmp L_while_test_mmx + + ALIGN 4 + 000005C4 L_test_for_second_level_length_mmx: + 000005C4 A8 40 test al,64 + 000005C6 0F 85 000000DE jnz L_test_for_end_of_block + + 000005CC 83 E0 0F and eax,15 + 000005CF 0F D3 C1 psrlq mm0,mm1 + 000005D2 0F 7E C1 movd ecx,mm0 + 000005D5 23 0C 85 and ecx, [inflate_fast_mask+eax*4] + 0000007C R + 000005DC 03 CA add ecx,edx + 000005DE 8B 04 8B mov eax, [ebx+ecx*4] + 000005E1 E9 FFFFFECC jmp L_dolen_mmx + + ALIGN 4 + 000005E8 L_test_for_second_level_dist_mmx: + 000005E8 A8 40 test al,64 + 000005EA 0F 85 000000AE jnz L_invalid_distance_code + + 000005F0 83 E0 0F and eax,15 + 000005F3 0F D3 C1 psrlq mm0,mm1 + 000005F6 0F 7E C1 movd ecx,mm0 + 000005F9 23 0C 85 and ecx, [inflate_fast_mask+eax*4] + 0000007C R + 00000600 8B 44 24 0C mov eax, [esp+12] + 00000604 03 CB add ecx,ebx + 00000606 8B 04 88 mov eax, [eax+ecx*4] + 00000609 E9 FFFFFF19 jmp L_dodist_mmx + + ALIGN 4 + 00000610 L_clip_window_mmx: + + 00000610 8B C8 mov ecx,eax + 00000612 8B 44 24 34 mov eax, [esp+52] + 00000616 F7 D9 neg ecx + 00000618 8B 74 24 38 mov esi, [esp+56] + + 0000061C 3B C3 cmp eax,ebx + 0000061E 0F 82 000000A2 jb L_invalid_distance_too_far + + 00000624 03 CB add ecx,ebx + 00000626 83 7C 24 30 00 cmp dword ptr [esp+48],0 + 0000062B 75 20 jne L_wrap_around_window_mmx + + 0000062D 2B C1 sub eax,ecx + 0000062F 03 F0 add esi,eax + + 00000631 3B D1 cmp edx,ecx + 00000633 76 58 jbe L_do_copy1_mmx + + 00000635 2B D1 sub edx,ecx + 00000637 F3/ A4 rep movsb + 00000639 8B F7 mov esi,edi + 0000063B 2B F3 sub esi,ebx + 0000063D EB 4E jmp L_do_copy1_mmx + + 0000063F 3B D1 cmp edx,ecx + 00000641 76 4A jbe L_do_copy1_mmx + + 00000643 2B D1 sub edx,ecx + 00000645 F3/ A4 rep movsb + 00000647 8B F7 mov esi,edi + 00000649 2B F3 sub esi,ebx + 0000064B EB 40 jmp L_do_copy1_mmx + + 0000064D L_wrap_around_window_mmx: + + 0000064D 8B 44 24 30 mov eax, [esp+48] + 00000651 3B C8 cmp ecx,eax + 00000653 76 28 jbe L_contiguous_in_window_mmx + + 00000655 03 74 24 34 add esi, [esp+52] + 00000659 03 F0 add esi,eax + 0000065B 2B F1 sub esi,ecx + 0000065D 2B C8 sub ecx,eax + + + 0000065F 3B D1 cmp edx,ecx + 00000661 76 2A jbe L_do_copy1_mmx + + 00000663 2B D1 sub edx,ecx + 00000665 F3/ A4 rep movsb + 00000667 8B 74 24 38 mov esi, [esp+56] + 0000066B 8B 4C 24 30 mov ecx, [esp+48] + 0000066F 3B D1 cmp edx,ecx + 00000671 76 1A jbe L_do_copy1_mmx + + 00000673 2B D1 sub edx,ecx + 00000675 F3/ A4 rep movsb + 00000677 8B F7 mov esi,edi + 00000679 2B F3 sub esi,ebx + 0000067B EB 10 jmp L_do_copy1_mmx + + 0000067D L_contiguous_in_window_mmx: + + 0000067D 03 F0 add esi,eax + 0000067F 2B F1 sub esi,ecx + + + 00000681 3B D1 cmp edx,ecx + 00000683 76 08 jbe L_do_copy1_mmx + + 00000685 2B D1 sub edx,ecx + 00000687 F3/ A4 rep movsb + 00000689 8B F7 mov esi,edi + 0000068B 2B F3 sub esi,ebx + + 0000068D L_do_copy1_mmx: + + + 0000068D 8B CA mov ecx,edx + 0000068F F3/ A4 rep movsb + + 00000691 8B 74 24 2C mov esi, [esp+44] + 00000695 8B 5C 24 08 mov ebx, [esp+8] + 00000699 E9 FFFFFE24 jmp L_while_test_mmx + ; 1174 "inffast.S" + 0000069E L_invalid_distance_code: + + + + + + 0000069E B9 00000044 R mov ecx, invalid_distance_code_msg + 000006A3 BA 0000001A mov edx,INFLATE_MODE_BAD + 000006A8 EB 2C jmp L_update_stream_state + + 000006AA L_test_for_end_of_block: + + + + + + 000006AA A8 20 test al,32 + 000006AC 74 0C jz L_invalid_literal_length_code + + 000006AE B9 00000000 mov ecx,0 + 000006B3 BA 0000000B mov edx,INFLATE_MODE_TYPE + 000006B8 EB 1C jmp L_update_stream_state + + 000006BA L_invalid_literal_length_code: + + + + + + 000006BA B9 00000028 R mov ecx, invalid_literal_length_code_msg + 000006BF BA 0000001A mov edx,INFLATE_MODE_BAD + 000006C4 EB 10 jmp L_update_stream_state + + 000006C6 L_invalid_distance_too_far: + + + + 000006C6 8B 74 24 2C mov esi, [esp+44] + 000006CA B9 0000005C R mov ecx, invalid_distance_too_far_msg + 000006CF BA 0000001A mov edx,INFLATE_MODE_BAD + 000006D4 EB 00 jmp L_update_stream_state + + 000006D6 L_update_stream_state: + + 000006D6 8B 44 24 58 mov eax, [esp+88] + 000006DA 85 C9 test ecx,ecx + 000006DC 74 03 jz L_skip_msg + 000006DE 89 48 18 mov [eax+24],ecx + 000006E1 L_skip_msg: + 000006E1 8B 40 1C mov eax, [eax+28] + 000006E4 89 10 mov [eax+mode_state],edx + 000006E6 EB 00 jmp L_break_loop + + ALIGN 4 + 000006E8 L_break_loop: + ; 1243 "inffast.S" + 000006E8 83 3D 00000000 R cmp dword ptr [inflate_fast_use_mmx],2 + 02 + 000006EF 75 02 jne L_update_next_in + + + + 000006F1 8B DD mov ebx,ebp + + 000006F3 L_update_next_in: + ; 1266 "inffast.S" + 000006F3 8B 44 24 58 mov eax, [esp+88] + 000006F7 8B CB mov ecx,ebx + 000006F9 8B 50 1C mov edx, [eax+28] + 000006FC C1 E9 03 shr ecx,3 + 000006FF 2B F1 sub esi,ecx + 00000701 C1 E1 03 shl ecx,3 + 00000704 2B D9 sub ebx,ecx + 00000706 89 78 0C mov [eax+12],edi + 00000709 89 5A 3C mov [edx+bits_state],ebx + 0000070C 8B CB mov ecx,ebx + + 0000070E 8D 5C 24 1C lea ebx, [esp+28] + 00000712 39 5C 24 14 cmp [esp+20],ebx + 00000716 75 14 jne L_buf_not_used + + 00000718 2B F3 sub esi,ebx + 0000071A 8B 18 mov ebx, [eax+0] + 0000071C 89 5C 24 14 mov [esp+20],ebx + 00000720 03 F3 add esi,ebx + 00000722 8B 58 04 mov ebx, [eax+4] + 00000725 83 EB 0B sub ebx,11 + 00000728 01 5C 24 14 add [esp+20],ebx + + 0000072C L_buf_not_used: + 0000072C 89 30 mov [eax+0],esi + + 0000072E BB 00000001 mov ebx,1 + 00000733 D3 E3 shl ebx,cl + 00000735 4B dec ebx + + + + + + 00000736 83 3D 00000000 R cmp dword ptr [inflate_fast_use_mmx],2 + 02 + 0000073D 75 08 jne L_update_hold + + + + 0000073F 0F D3 C1 psrlq mm0,mm1 + 00000742 0F 7E C5 movd ebp,mm0 + + 00000745 0F 77 emms + + 00000747 L_update_hold: + + + + 00000747 23 EB and ebp,ebx + 00000749 89 6A 38 mov [edx+hold_state],ebp + + + + + 0000074C 8B 5C 24 14 mov ebx, [esp+20] + 00000750 3B DE cmp ebx,esi + 00000752 76 0A jbe L_last_is_smaller + + 00000754 2B DE sub ebx,esi + 00000756 83 C3 0B add ebx,11 + 00000759 89 58 04 mov [eax+4],ebx + 0000075C EB 0A jmp L_fixup_out + 0000075E L_last_is_smaller: + 0000075E 2B F3 sub esi,ebx + 00000760 F7 DE neg esi + 00000762 83 C6 0B add esi,11 + 00000765 89 70 04 mov [eax+4],esi + + + + + 00000768 L_fixup_out: + + 00000768 8B 5C 24 10 mov ebx, [esp+16] + 0000076C 3B DF cmp ebx,edi + 0000076E 76 0D jbe L_end_is_smaller + + 00000770 2B DF sub ebx,edi + 00000772 81 C3 00000101 add ebx,257 + 00000778 89 58 10 mov [eax+16],ebx + 0000077B EB 0D jmp L_done + 0000077D L_end_is_smaller: + 0000077D 2B FB sub edi,ebx + 0000077F F7 DF neg edi + 00000781 81 C7 00000101 add edi,257 + 00000787 89 78 10 mov [eax+16],edi + + + + + + 0000078A L_done: + 0000078A 83 C4 40 add esp,64 + 0000078D 9D popfd + 0000078E 5B pop ebx + 0000078F 5D pop ebp + 00000790 5E pop esi + 00000791 5F pop edi + 00000792 C3 ret + 00000793 _inflate_fast endp + + 00000004 _TEXT ends + end + Microsoft (R) Macro Assembler Version 12.00.31101.0 05/22/17 22:38:56 +inffas32.asm Symbols 2 - 1 + + + + +Segments and Groups: + + N a m e Size Length Align Combine Class + +FLAT . . . . . . . . . . . . . . GROUP +_DATA . . . . . . . . . . . . . 32 Bit 00000004 Para Public 'DATA' +_TEXT . . . . . . . . . . . . . 32 Bit 00000793 Para Public 'CODE' + + +Procedures, parameters, and locals: + + N a m e Type Value Attr + +_inflate_fast . . . . . . . . . P Near 00000100 _TEXT Length= 00000693 Public + L_align_long . . . . . . . . . L Near 000001BA _TEXT + L_is_aligned . . . . . . . . . L Near 000001D2 _TEXT + L_check_mmx . . . . . . . . . L Near 000001D6 _TEXT + L_use_mmx . . . . . . . . . . L Near 00000233 _TEXT + L_dont_use_mmx . . . . . . . . L Near 0000023F _TEXT + L_check_mmx_pop . . . . . . . L Near 00000249 _TEXT + L_do_loop . . . . . . . . . . L Near 00000250 _TEXT + L_get_length_code . . . . . . L Near 00000262 _TEXT + L_dolen . . . . . . . . . . . L Near 0000026E _TEXT + L_while_test . . . . . . . . . L Near 0000027C _TEXT + L_test_for_length_base . . . . L Near 00000291 _TEXT + L_add_bits_to_len . . . . . . L Near 000002BA _TEXT + L_save_len . . . . . . . . . . L Near 000002CA _TEXT + L_decode_distance . . . . . . L Near 000002CE _TEXT + L_get_distance_code . . . . . L Near 000002E0 _TEXT + L_dodist . . . . . . . . . . . L Near 000002ED _TEXT + L_add_bits_to_dist . . . . . . L Near 0000031C _TEXT + L_check_window . . . . . . . . L Near 0000032E _TEXT + L_check_dist_one . . . . . . . L Near 0000036C _TEXT + L_test_for_second_level_length . L Near 00000394 _TEXT + L_test_for_second_level_dist . L Near 000003B4 _TEXT + L_clip_window . . . . . . . . L Near 000003D4 _TEXT + L_wrap_around_window . . . . . L Near 00000415 _TEXT + L_contiguous_in_window . . . . L Near 00000449 _TEXT + L_do_copy1 . . . . . . . . . . L Near 0000045D _TEXT + L_init_mmx . . . . . . . . . . L Near 0000046C _TEXT + L_do_loop_mmx . . . . . . . . L Near 0000048C _TEXT + L_get_length_code_mmx . . . . L Near 000004A6 _TEXT + L_dolen_mmx . . . . . . . . . L Near 000004B2 _TEXT + L_while_test_mmx . . . . . . . L Near 000004C2 _TEXT + L_test_for_length_base_mmx . . L Near 000004D7 _TEXT + L_decode_distance_mmx . . . . L Near 000004FD _TEXT + L_get_dist_code_mmx . . . . . L Near 00000517 _TEXT + L_dodist_mmx . . . . . . . . . L Near 00000527 _TEXT + L_add_bits_to_dist_mmx . . . . L Near 00000541 _TEXT + L_check_window_mmx . . . . . . L Near 00000555 _TEXT + L_check_dist_one_mmx . . . . . L Near 00000598 _TEXT + L_test_for_second_level_length_mmx . L Near 000005C4 _TEXT + L_test_for_second_level_dist_mmx . L Near 000005E8 _TEXT + L_clip_window_mmx . . . . . . L Near 00000610 _TEXT + L_wrap_around_window_mmx . . . L Near 0000064D _TEXT + L_contiguous_in_window_mmx . . L Near 0000067D _TEXT + L_do_copy1_mmx . . . . . . . . L Near 0000068D _TEXT + L_invalid_distance_code . . . L Near 0000069E _TEXT + L_test_for_end_of_block . . . L Near 000006AA _TEXT + L_invalid_literal_length_code L Near 000006BA _TEXT + L_invalid_distance_too_far . . L Near 000006C6 _TEXT + L_update_stream_state . . . . L Near 000006D6 _TEXT + L_skip_msg . . . . . . . . . . L Near 000006E1 _TEXT + L_break_loop . . . . . . . . . L Near 000006E8 _TEXT + L_update_next_in . . . . . . . L Near 000006F3 _TEXT + L_buf_not_used . . . . . . . . L Near 0000072C _TEXT + L_update_hold . . . . . . . . L Near 00000747 _TEXT + L_last_is_smaller . . . . . . L Near 0000075E _TEXT + L_fixup_out . . . . . . . . . L Near 00000768 _TEXT + L_end_is_smaller . . . . . . . L Near 0000077D _TEXT + L_done . . . . . . . . . . . . L Near 0000078A _TEXT + + +Symbols: + + N a m e Type Value Attr + +@CodeSize . . . . . . . . . . . Number 00000000h +@DataSize . . . . . . . . . . . Number 00000000h +@Interface . . . . . . . . . . . Number 00000000h +@Model . . . . . . . . . . . . . Number 00000007h +@code . . . . . . . . . . . . . Text _TEXT +@data . . . . . . . . . . . . . Text FLAT +@fardata? . . . . . . . . . . . Text FLAT +@fardata . . . . . . . . . . . . Text FLAT +@stack . . . . . . . . . . . . . Text FLAT +INFLATE_MODE_BAD . . . . . . . . Number 0000001Ah +INFLATE_MODE_TYPE . . . . . . . Number 0000000Bh +bits_state . . . . . . . . . . . Number 0000003Ch +distbits_state . . . . . . . . . Number 00000058h +distcode_state . . . . . . . . . Number 00000050h +hold_state . . . . . . . . . . . Number 00000038h +inflate_fast_mask . . . . . . . L Near 0000007C _TEXT +inflate_fast_use_mmx . . . . . . L Near 00000000 _DATA +invalid_distance_code_msg . . . L Near 00000044 _TEXT +invalid_distance_too_far_msg . . L Near 0000005C _TEXT +invalid_literal_length_code_msg L Near 00000028 _TEXT +lenbits_state . . . . . . . . . Number 00000054h +lencode_state . . . . . . . . . Number 0000004Ch +mode_state . . . . . . . . . . . Number 00000000h +window_state . . . . . . . . . . Number 00000034h +write_state . . . . . . . . . . Number 00000030h +wsize_state . . . . . . . . . . Number 00000028h +zlib1222sup . . . . . . . . . . Number 00000008h + + 0 Warnings + 0 Errors diff --git a/libz/contrib/masmx86/match686.asm b/libz/contrib/masmx86/match686.asm new file mode 100644 index 000000000..3b09212f8 --- /dev/null +++ b/libz/contrib/masmx86/match686.asm @@ -0,0 +1,479 @@ +; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86 +; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; File written by Gilles Vollant, by converting match686.S from Brian Raiter +; for MASM. This is as assembly version of longest_match +; from Jean-loup Gailly in deflate.c +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; For Visual C++ 4.x and higher and ML 6.x and higher +; ml.exe is distributed in +; http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64 +; +; this file contain two implementation of longest_match +; +; this longest_match was written by Brian raiter (1998), optimized for Pentium Pro +; (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom) +; +; for using an assembly version of longest_match, you need define ASMV in project +; +; compile the asm file running +; ml /coff /Zi /c /Flmatch686.lst match686.asm +; and do not include match686.obj in your project +; +; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for +; Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor +; with autoselect (with cpu detection code) +; if you want support the old pentium optimization, you can still use these version +; +; this file is not optimized for old pentium, but it compatible with all x86 32 bits +; processor (starting 80386) +; +; +; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2 + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; /* current match */ + + NbStack equ 76 + cur_match equ dword ptr[esp+NbStack-0] + str_s equ dword ptr[esp+NbStack-4] +; 5 dword on top (ret,ebp,esi,edi,ebx) + adrret equ dword ptr[esp+NbStack-8] + pushebp equ dword ptr[esp+NbStack-12] + pushedi equ dword ptr[esp+NbStack-16] + pushesi equ dword ptr[esp+NbStack-20] + pushebx equ dword ptr[esp+NbStack-24] + + chain_length equ dword ptr [esp+NbStack-28] + limit equ dword ptr [esp+NbStack-32] + best_len equ dword ptr [esp+NbStack-36] + window equ dword ptr [esp+NbStack-40] + prev equ dword ptr [esp+NbStack-44] + scan_start equ word ptr [esp+NbStack-48] + wmask equ dword ptr [esp+NbStack-52] + match_start_ptr equ dword ptr [esp+NbStack-56] + nice_match equ dword ptr [esp+NbStack-60] + scan equ dword ptr [esp+NbStack-64] + + windowlen equ dword ptr [esp+NbStack-68] + match_start equ dword ptr [esp+NbStack-72] + strend equ dword ptr [esp+NbStack-76] + NbStackAdd equ (NbStack-24) + + .386p + + name gvmatch + .MODEL FLAT + + + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + + zlib1222add equ 8 + +; Note : these value are good with a 8 bytes boundary pack structure + dep_chain_length equ 74h+zlib1222add + dep_window equ 30h+zlib1222add + dep_strstart equ 64h+zlib1222add + dep_prev_length equ 70h+zlib1222add + dep_nice_match equ 88h+zlib1222add + dep_w_size equ 24h+zlib1222add + dep_prev equ 38h+zlib1222add + dep_w_mask equ 2ch+zlib1222add + dep_good_match equ 84h+zlib1222add + dep_match_start equ 68h+zlib1222add + dep_lookahead equ 6ch+zlib1222add + + +_TEXT segment + +IFDEF NOUNDERLINE + public longest_match + public match_init +ELSE + public _longest_match + public _match_init +ENDIF + + MAX_MATCH equ 258 + MIN_MATCH equ 3 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1) +MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h) + + +;;; stack frame offsets + +chainlenwmask equ esp + 0 ; high word: current chain len + ; low word: s->wmask +window equ esp + 4 ; local copy of s->window +windowbestlen equ esp + 8 ; s->window + bestlen +scanstart equ esp + 16 ; first two bytes of string +scanend equ esp + 12 ; last two bytes of string +scanalign equ esp + 20 ; dword-misalignment of string +nicematch equ esp + 24 ; a good enough match size +bestlen equ esp + 28 ; size of best match so far +scan equ esp + 32 ; ptr to string wanting match + +LocalVarsSize equ 36 +; saved ebx byte esp + 36 +; saved edi byte esp + 40 +; saved esi byte esp + 44 +; saved ebp byte esp + 48 +; return address byte esp + 52 +deflatestate equ esp + 56 ; the function arguments +curmatch equ esp + 60 + +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +dsWSize equ 36+zlib1222add +dsWMask equ 44+zlib1222add +dsWindow equ 48+zlib1222add +dsPrev equ 56+zlib1222add +dsMatchLen equ 88+zlib1222add +dsPrevMatch equ 92+zlib1222add +dsStrStart equ 100+zlib1222add +dsMatchStart equ 104+zlib1222add +dsLookahead equ 108+zlib1222add +dsPrevLen equ 112+zlib1222add +dsMaxChainLen equ 116+zlib1222add +dsGoodMatch equ 132+zlib1222add +dsNiceMatch equ 136+zlib1222add + + +;;; match686.asm -- Pentium-Pro-optimized version of longest_match() +;;; Written for zlib 1.1.2 +;;; Copyright (C) 1998 Brian Raiter +;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html +;;; +;; +;; This software is provided 'as-is', without any express or implied +;; warranty. In no event will the authors be held liable for any damages +;; arising from the use of this software. +;; +;; Permission is granted to anyone to use this software for any purpose, +;; including commercial applications, and to alter it and redistribute it +;; freely, subject to the following restrictions: +;; +;; 1. The origin of this software must not be misrepresented; you must not +;; claim that you wrote the original software. If you use this software +;; in a product, an acknowledgment in the product documentation would be +;; appreciated but is not required. +;; 2. Altered source versions must be plainly marked as such, and must not be +;; misrepresented as being the original software +;; 3. This notice may not be removed or altered from any source distribution. +;; + +;GLOBAL _longest_match, _match_init + + +;SECTION .text + +;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch) + +;_longest_match: + IFDEF NOUNDERLINE + longest_match proc near + ELSE + _longest_match proc near + ENDIF +.FPO (9, 4, 0, 0, 1, 0) + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + push ebp + push edi + push esi + push ebx + sub esp, LocalVarsSize + +;;; Retrieve the function arguments. ecx will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + + mov edx, [deflatestate] + mov ecx, [curmatch] + +;;; uInt wmask = s->w_mask; +;;; unsigned chain_length = s->max_chain_length; +;;; if (s->prev_length >= s->good_match) { +;;; chain_length >>= 2; +;;; } + + mov eax, [edx + dsPrevLen] + mov ebx, [edx + dsGoodMatch] + cmp eax, ebx + mov eax, [edx + dsWMask] + mov ebx, [edx + dsMaxChainLen] + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +;;; chainlen is decremented once beforehand so that the function can +;;; use the sign flag instead of the zero flag for the exit test. +;;; It is then shifted into the high word, to make room for the wmask +;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + mov [chainlenwmask], ebx + +;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + mov eax, [edx + dsNiceMatch] + mov ebx, [edx + dsLookahead] + cmp ebx, eax + jl LookaheadLess + mov ebx, eax +LookaheadLess: mov [nicematch], ebx + +;;; register Bytef *scan = s->window + s->strstart; + + mov esi, [edx + dsWindow] + mov [window], esi + mov ebp, [edx + dsStrStart] + lea edi, [esi + ebp] + mov [scan], edi + +;;; Determine how many bytes the scan ptr is off from being +;;; dword-aligned. + + mov eax, edi + neg eax + and eax, 3 + mov [scanalign], eax + +;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +;;; s->strstart - (IPos)MAX_DIST(s) : NIL; + + mov eax, [edx + dsWSize] + sub eax, MIN_LOOKAHEAD + sub ebp, eax + jg LimitPositive + xor ebp, ebp +LimitPositive: + +;;; int best_len = s->prev_length; + + mov eax, [edx + dsPrevLen] + mov [bestlen], eax + +;;; Store the sum of s->window + best_len in esi locally, and in esi. + + add esi, eax + mov [windowbestlen], esi + +;;; register ush scan_start = *(ushf*)scan; +;;; register ush scan_end = *(ushf*)(scan+best_len-1); +;;; Posf *prev = s->prev; + + movzx ebx, word ptr [edi] + mov [scanstart], ebx + movzx ebx, word ptr [edi + eax - 1] + mov [scanend], ebx + mov edi, [edx + dsPrev] + +;;; Jump into the main loop. + + mov edx, [chainlenwmask] + jmp short LoopEntry + +align 4 + +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; ecx = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit + +LookupLoop: + and ecx, edx + movzx ecx, word ptr [edi + ecx*2] + cmp ecx, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow +LoopEntry: movzx eax, word ptr [esi + ecx - 1] + cmp eax, ebx + jnz LookupLoop + mov eax, [window] + movzx eax, word ptr [eax + ecx] + cmp eax, [scanstart] + jnz LookupLoop + +;;; Store the current value of chainlen. + + mov [chainlenwmask], edx + +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). + + mov esi, [window] + mov edi, [scan] + add esi, ecx + mov eax, [scanalign] + mov edx, 0fffffef8h; -(MAX_MATCH_8) + lea edi, [edi + eax + 0108h] ;MAX_MATCH_8] + lea esi, [esi + eax + 0108h] ;MAX_MATCH_8] + +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust edx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (esi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. + +LoopCmps: + mov eax, [esi + edx] + xor eax, [edi + edx] + jnz LeaveLoopCmps + mov eax, [esi + edx + 4] + xor eax, [edi + edx + 4] + jnz LeaveLoopCmps4 + add edx, 8 + jnz LoopCmps + jmp short LenMaximum +LeaveLoopCmps4: add edx, 4 +LeaveLoopCmps: test eax, 0000FFFFh + jnz LenLower + add edx, 2 + shr eax, 16 +LenLower: sub al, 1 + adc edx, 0 + +;;; Calculate the length of the match. If it is longer than MAX_MATCH, +;;; then automatically accept it as the best possible match and leave. + + lea eax, [edi + edx] + mov edi, [scan] + sub eax, edi + cmp eax, MAX_MATCH + jge LenMaximum + +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. + + mov edx, [deflatestate] + mov ebx, [bestlen] + cmp eax, ebx + jg LongerMatch + mov esi, [windowbestlen] + mov edi, [edx + dsPrev] + mov ebx, [scanend] + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); + +LongerMatch: mov ebx, [nicematch] + mov [bestlen], eax + mov [edx + dsMatchStart], ecx + cmp eax, ebx + jge LeaveNow + mov esi, [window] + add esi, eax + mov [windowbestlen], esi + movzx ebx, word ptr [edi + eax - 1] + mov edi, [edx + dsPrev] + mov [scanend], ebx + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; Accept the current string, with the maximum possible length. + +LenMaximum: mov edx, [deflatestate] + mov dword ptr [bestlen], MAX_MATCH + mov [edx + dsMatchStart], ecx + +;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +;;; return s->lookahead; + +LeaveNow: + mov edx, [deflatestate] + mov ebx, [bestlen] + mov eax, [edx + dsLookahead] + cmp ebx, eax + jg LookaheadRet + mov eax, ebx +LookaheadRet: + +;;; Restore the stack and return from whence we came. + + add esp, LocalVarsSize + pop ebx + pop esi + pop edi + pop ebp + + ret +; please don't remove this string ! +; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary! + db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah + + + IFDEF NOUNDERLINE + longest_match endp + ELSE + _longest_match endp + ENDIF + + IFDEF NOUNDERLINE + match_init proc near + ret + match_init endp + ELSE + _match_init proc near + ret + _match_init endp + ENDIF + + +_TEXT ends +end diff --git a/libz/contrib/masmx86/match686.lst b/libz/contrib/masmx86/match686.lst new file mode 100644 index 000000000..bc96b0cce --- /dev/null +++ b/libz/contrib/masmx86/match686.lst @@ -0,0 +1,624 @@ +Microsoft (R) Macro Assembler Version 12.00.31101.0 05/22/17 22:38:55 +match686.asm Page 1 - 1 + + + ; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86 + ; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant. + ; File written by Gilles Vollant, by converting match686.S from Brian Raiter + ; for MASM. This is as assembly version of longest_match + ; from Jean-loup Gailly in deflate.c + ; + ; http://www.zlib.net + ; http://www.winimage.com/zLibDll + ; http://www.muppetlabs.com/~breadbox/software/assembly.html + ; + ; For Visual C++ 4.x and higher and ML 6.x and higher + ; ml.exe is distributed in + ; http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64 + ; + ; this file contain two implementation of longest_match + ; + ; this longest_match was written by Brian raiter (1998), optimized for Pentium Pro + ; (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom) + ; + ; for using an assembly version of longest_match, you need define ASMV in project + ; + ; compile the asm file running + ; ml /coff /Zi /c /Flmatch686.lst match686.asm + ; and do not include match686.obj in your project + ; + ; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for + ; Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor + ; with autoselect (with cpu detection code) + ; if you want support the old pentium optimization, you can still use these version + ; + ; this file is not optimized for old pentium, but it compatible with all x86 32 bits + ; processor (starting 80386) + ; + ; + ; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2 + + ;uInt longest_match(s, cur_match) + ; deflate_state *s; + ; IPos cur_match; /* current match */ + + = 0000004C NbStack equ 76 + = dword ptr[esp+NbStack-0] cur_match equ dword ptr[esp+NbStack-0] + = dword ptr[esp+NbStack-4] str_s equ dword ptr[esp+NbStack-4] + ; 5 dword on top (ret,ebp,esi,edi,ebx) + = dword ptr[esp+NbStack-8] adrret equ dword ptr[esp+NbStack-8] + = dword ptr[esp+NbStack-12 pushebp equ dword ptr[esp+NbStack-12] + ] + = dword ptr[esp+NbStack-16 pushedi equ dword ptr[esp+NbStack-16] + ] + = dword ptr[esp+NbStack-20 pushesi equ dword ptr[esp+NbStack-20] + ] + = dword ptr[esp+NbStack-24 pushebx equ dword ptr[esp+NbStack-24] + ] + + = dword ptr [esp+NbStack-2 chain_length equ dword ptr [esp+NbStack-28] + 8] + = dword ptr [esp+NbStack-3 limit equ dword ptr [esp+NbStack-32] + 2] + = dword ptr [esp+NbStack-3 best_len equ dword ptr [esp+NbStack-36] + 6] + = dword ptr [esp+NbStack-4 window equ dword ptr [esp+NbStack-40] + 0] + = dword ptr [esp+NbStack-4 prev equ dword ptr [esp+NbStack-44] + 4] + = word ptr [esp+NbStack-48 scan_start equ word ptr [esp+NbStack-48] + ] + = dword ptr [esp+NbStack-5 wmask equ dword ptr [esp+NbStack-52] + 2] + = dword ptr [esp+NbStack-5 match_start_ptr equ dword ptr [esp+NbStack-56] + 6] + = dword ptr [esp+NbStack-6 nice_match equ dword ptr [esp+NbStack-60] + 0] + = dword ptr [esp+NbStack-6 scan equ dword ptr [esp+NbStack-64] + 4] + + = dword ptr [esp+NbStack-6 windowlen equ dword ptr [esp+NbStack-68] + 8] + = dword ptr [esp+NbStack-7 match_start equ dword ptr [esp+NbStack-72] + 2] + = dword ptr [esp+NbStack-7 strend equ dword ptr [esp+NbStack-76] + 6] + = 00000034 NbStackAdd equ (NbStack-24) + + .386p + + name gvmatch + .MODEL FLAT + + + + ; all the +zlib1222add offsets are due to the addition of fields + ; in zlib in the deflate_state structure since the asm code was first written + ; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). + ; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). + ; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + + = 00000008 zlib1222add equ 8 + + ; Note : these value are good with a 8 bytes boundary pack structure + = 0000007C dep_chain_length equ 74h+zlib1222add + = 00000038 dep_window equ 30h+zlib1222add + = 0000006C dep_strstart equ 64h+zlib1222add + = 00000078 dep_prev_length equ 70h+zlib1222add + = 00000090 dep_nice_match equ 88h+zlib1222add + = 0000002C dep_w_size equ 24h+zlib1222add + = 00000040 dep_prev equ 38h+zlib1222add + = 00000034 dep_w_mask equ 2ch+zlib1222add + = 0000008C dep_good_match equ 84h+zlib1222add + = 00000070 dep_match_start equ 68h+zlib1222add + = 00000074 dep_lookahead equ 6ch+zlib1222add + + + 00000000 _TEXT segment + + IFDEF NOUNDERLINE + ELSE + public _longest_match + public _match_init + ENDIF + + = 00000102 MAX_MATCH equ 258 + = 00000003 MIN_MATCH equ 3 + = 00000106 MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + + + = 00000102 MAX_MATCH equ 258 + = 00000003 MIN_MATCH equ 3 + = 00000106 MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1) + = 00000100 MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h) + + + ;;; stack frame offsets + + = esp + 0 chainlenwmask equ esp + 0 ; high word: current chain len + ; low word: s->wmask + = esp + 4 window equ esp + 4 ; local copy of s->window + = esp + 8 windowbestlen equ esp + 8 ; s->window + bestlen + = esp + 16 scanstart equ esp + 16 ; first two bytes of string + = esp + 12 scanend equ esp + 12 ; last two bytes of string + = esp + 20 scanalign equ esp + 20 ; dword-misalignment of string + = esp + 24 nicematch equ esp + 24 ; a good enough match size + = esp + 28 bestlen equ esp + 28 ; size of best match so far + = esp + 32 scan equ esp + 32 ; ptr to string wanting match + + = 00000024 LocalVarsSize equ 36 + ; saved ebx byte esp + 36 + ; saved edi byte esp + 40 + ; saved esi byte esp + 44 + ; saved ebp byte esp + 48 + ; return address byte esp + 52 + = esp + 56 deflatestate equ esp + 56 ; the function arguments + = esp + 60 curmatch equ esp + 60 + + ;;; Offsets for fields in the deflate_state structure. These numbers + ;;; are calculated from the definition of deflate_state, with the + ;;; assumption that the compiler will dword-align the fields. (Thus, + ;;; changing the definition of deflate_state could easily cause this + ;;; program to crash horribly, without so much as a warning at + ;;; compile time. Sigh.) + + = 0000002C dsWSize equ 36+zlib1222add + = 00000034 dsWMask equ 44+zlib1222add + = 00000038 dsWindow equ 48+zlib1222add + = 00000040 dsPrev equ 56+zlib1222add + = 00000060 dsMatchLen equ 88+zlib1222add + = 00000064 dsPrevMatch equ 92+zlib1222add + = 0000006C dsStrStart equ 100+zlib1222add + = 00000070 dsMatchStart equ 104+zlib1222add + = 00000074 dsLookahead equ 108+zlib1222add + = 00000078 dsPrevLen equ 112+zlib1222add + = 0000007C dsMaxChainLen equ 116+zlib1222add + = 0000008C dsGoodMatch equ 132+zlib1222add + = 00000090 dsNiceMatch equ 136+zlib1222add + + + ;;; match686.asm -- Pentium-Pro-optimized version of longest_match() + ;;; Written for zlib 1.1.2 + ;;; Copyright (C) 1998 Brian Raiter + ;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html + ;;; + ;; + ;; This software is provided 'as-is', without any express or implied + ;; warranty. In no event will the authors be held liable for any damages + ;; arising from the use of this software. + ;; + ;; Permission is granted to anyone to use this software for any purpose, + ;; including commercial applications, and to alter it and redistribute it + ;; freely, subject to the following restrictions: + ;; + ;; 1. The origin of this software must not be misrepresented; you must not + ;; claim that you wrote the original software. If you use this software + ;; in a product, an acknowledgment in the product documentation would be + ;; appreciated but is not required. + ;; 2. Altered source versions must be plainly marked as such, and must not be + ;; misrepresented as being the original software + ;; 3. This notice may not be removed or altered from any source distribution. + ;; + + ;GLOBAL _longest_match, _match_init + + + ;SECTION .text + + ;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch) + + ;_longest_match: + IFDEF NOUNDERLINE + ELSE + 00000000 _longest_match proc near + ENDIF + 00000000 .FPO (9, 4, 0, 0, 1, 0) + + ;;; Save registers that the compiler may be using, and adjust esp to + ;;; make room for our stack frame. + + 00000000 55 push ebp + 00000001 57 push edi + 00000002 56 push esi + 00000003 53 push ebx + 00000004 83 EC 24 sub esp, LocalVarsSize + + ;;; Retrieve the function arguments. ecx will hold cur_match + ;;; throughout the entire function. edx will hold the pointer to the + ;;; deflate_state structure during the function's setup (before + ;;; entering the main loop. + + 00000007 8B 54 24 38 mov edx, [deflatestate] + 0000000B 8B 4C 24 3C mov ecx, [curmatch] + + ;;; uInt wmask = s->w_mask; + ;;; unsigned chain_length = s->max_chain_length; + ;;; if (s->prev_length >= s->good_match) { + ;;; chain_length >>= 2; + ;;; } + + 0000000F 8B 42 78 mov eax, [edx + dsPrevLen] + 00000012 8B 9A 0000008C mov ebx, [edx + dsGoodMatch] + 00000018 3B C3 cmp eax, ebx + 0000001A 8B 42 34 mov eax, [edx + dsWMask] + 0000001D 8B 5A 7C mov ebx, [edx + dsMaxChainLen] + 00000020 7C 03 jl LastMatchGood + 00000022 C1 EB 02 shr ebx, 2 + 00000025 LastMatchGood: + + ;;; chainlen is decremented once beforehand so that the function can + ;;; use the sign flag instead of the zero flag for the exit test. + ;;; It is then shifted into the high word, to make room for the wmask + ;;; value, which it will always accompany. + + 00000025 4B dec ebx + 00000026 C1 E3 10 shl ebx, 16 + 00000029 0B D8 or ebx, eax + 0000002B 89 1C 24 mov [chainlenwmask], ebx + + ;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + 0000002E 8B 82 00000090 mov eax, [edx + dsNiceMatch] + 00000034 8B 5A 74 mov ebx, [edx + dsLookahead] + 00000037 3B D8 cmp ebx, eax + 00000039 7C 02 jl LookaheadLess + 0000003B 8B D8 mov ebx, eax + 0000003D 89 5C 24 18 LookaheadLess: mov [nicematch], ebx + + ;;; register Bytef *scan = s->window + s->strstart; + + 00000041 8B 72 38 mov esi, [edx + dsWindow] + 00000044 89 74 24 04 mov [window], esi + 00000048 8B 6A 6C mov ebp, [edx + dsStrStart] + 0000004B 8D 7C 35 00 lea edi, [esi + ebp] + 0000004F 89 7C 24 20 mov [scan], edi + + ;;; Determine how many bytes the scan ptr is off from being + ;;; dword-aligned. + + 00000053 8B C7 mov eax, edi + 00000055 F7 D8 neg eax + 00000057 83 E0 03 and eax, 3 + 0000005A 89 44 24 14 mov [scanalign], eax + + ;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + ;;; s->strstart - (IPos)MAX_DIST(s) : NIL; + + 0000005E 8B 42 2C mov eax, [edx + dsWSize] + 00000061 2D 00000106 sub eax, MIN_LOOKAHEAD + 00000066 2B E8 sub ebp, eax + 00000068 7F 02 jg LimitPositive + 0000006A 33 ED xor ebp, ebp + 0000006C LimitPositive: + + ;;; int best_len = s->prev_length; + + 0000006C 8B 42 78 mov eax, [edx + dsPrevLen] + 0000006F 89 44 24 1C mov [bestlen], eax + + ;;; Store the sum of s->window + best_len in esi locally, and in esi. + + 00000073 03 F0 add esi, eax + 00000075 89 74 24 08 mov [windowbestlen], esi + + ;;; register ush scan_start = *(ushf*)scan; + ;;; register ush scan_end = *(ushf*)(scan+best_len-1); + ;;; Posf *prev = s->prev; + + 00000079 0F B7 1F movzx ebx, word ptr [edi] + 0000007C 89 5C 24 10 mov [scanstart], ebx + 00000080 0F B7 5C 38 FF movzx ebx, word ptr [edi + eax - 1] + 00000085 89 5C 24 0C mov [scanend], ebx + 00000089 8B 7A 40 mov edi, [edx + dsPrev] + + ;;; Jump into the main loop. + + 0000008C 8B 14 24 mov edx, [chainlenwmask] + 0000008F EB 1D jmp short LoopEntry + + align 4 + + ;;; do { + ;;; match = s->window + cur_match; + ;;; if (*(ushf*)(match+best_len-1) != scan_end || + ;;; *(ushf*)match != scan_start) continue; + ;;; [...] + ;;; } while ((cur_match = prev[cur_match & wmask]) > limit + ;;; && --chain_length != 0); + ;;; + ;;; Here is the inner loop of the function. The function will spend the + ;;; majority of its time in this loop, and majority of that time will + ;;; be spent in the first ten instructions. + ;;; + ;;; Within this loop: + ;;; ebx = scanend + ;;; ecx = curmatch + ;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) + ;;; esi = windowbestlen - i.e., (window + bestlen) + ;;; edi = prev + ;;; ebp = limit + + 00000094 LookupLoop: + 00000094 23 CA and ecx, edx + 00000096 0F B7 0C 4F movzx ecx, word ptr [edi + ecx*2] + 0000009A 3B CD cmp ecx, ebp + 0000009C 0F 86 000000E0 jbe LeaveNow + 000000A2 81 EA 00010000 sub edx, 00010000h + 000000A8 0F 88 000000D4 js LeaveNow + 000000AE 0F B7 44 31 FF LoopEntry: movzx eax, word ptr [esi + ecx - 1] + 000000B3 3B C3 cmp eax, ebx + 000000B5 75 DD jnz LookupLoop + 000000B7 8B 44 24 04 mov eax, [window] + 000000BB 0F B7 04 01 movzx eax, word ptr [eax + ecx] + 000000BF 3B 44 24 10 cmp eax, [scanstart] + 000000C3 75 CF jnz LookupLoop + + ;;; Store the current value of chainlen. + + 000000C5 89 14 24 mov [chainlenwmask], edx + + ;;; Point edi to the string under scrutiny, and esi to the string we + ;;; are hoping to match it up with. In actuality, esi and edi are + ;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is + ;;; initialized to -(MAX_MATCH_8 - scanalign). + + 000000C8 8B 74 24 04 mov esi, [window] + 000000CC 8B 7C 24 20 mov edi, [scan] + 000000D0 03 F1 add esi, ecx + 000000D2 8B 44 24 14 mov eax, [scanalign] + 000000D6 BA FFFFFEF8 mov edx, 0fffffef8h; -(MAX_MATCH_8) + 000000DB 8D BC 38 lea edi, [edi + eax + 0108h] ;MAX_MATCH_8] + 00000108 + 000000E2 8D B4 30 lea esi, [esi + eax + 0108h] ;MAX_MATCH_8] + 00000108 + + ;;; Test the strings for equality, 8 bytes at a time. At the end, + ;;; adjust edx so that it is offset to the exact byte that mismatched. + ;;; + ;;; We already know at this point that the first three bytes of the + ;;; strings match each other, and they can be safely passed over before + ;;; starting the compare loop. So what this code does is skip over 0-3 + ;;; bytes, as much as necessary in order to dword-align the edi + ;;; pointer. (esi will still be misaligned three times out of four.) + ;;; + ;;; It should be confessed that this loop usually does not represent + ;;; much of the total running time. Replacing it with a more + ;;; straightforward "rep cmpsb" would not drastically degrade + ;;; performance. + + 000000E9 LoopCmps: + 000000E9 8B 04 32 mov eax, [esi + edx] + 000000EC 33 04 3A xor eax, [edi + edx] + 000000EF 75 14 jnz LeaveLoopCmps + 000000F1 8B 44 32 04 mov eax, [esi + edx + 4] + 000000F5 33 44 3A 04 xor eax, [edi + edx + 4] + 000000F9 75 07 jnz LeaveLoopCmps4 + 000000FB 83 C2 08 add edx, 8 + 000000FE 75 E9 jnz LoopCmps + 00000100 EB 71 jmp short LenMaximum + 00000102 83 C2 04 LeaveLoopCmps4: add edx, 4 + 00000105 A9 0000FFFF LeaveLoopCmps: test eax, 0000FFFFh + 0000010A 75 06 jnz LenLower + 0000010C 83 C2 02 add edx, 2 + 0000010F C1 E8 10 shr eax, 16 + 00000112 2C 01 LenLower: sub al, 1 + 00000114 83 D2 00 adc edx, 0 + + ;;; Calculate the length of the match. If it is longer than MAX_MATCH, + ;;; then automatically accept it as the best possible match and leave. + + 00000117 8D 04 3A lea eax, [edi + edx] + 0000011A 8B 7C 24 20 mov edi, [scan] + 0000011E 2B C7 sub eax, edi + 00000120 3D 00000102 cmp eax, MAX_MATCH + 00000125 7D 4C jge LenMaximum + + ;;; If the length of the match is not longer than the best match we + ;;; have so far, then forget it and return to the lookup loop. + + 00000127 8B 54 24 38 mov edx, [deflatestate] + 0000012B 8B 5C 24 1C mov ebx, [bestlen] + 0000012F 3B C3 cmp eax, ebx + 00000131 7F 13 jg LongerMatch + 00000133 8B 74 24 08 mov esi, [windowbestlen] + 00000137 8B 7A 40 mov edi, [edx + dsPrev] + 0000013A 8B 5C 24 0C mov ebx, [scanend] + 0000013E 8B 14 24 mov edx, [chainlenwmask] + 00000141 E9 FFFFFF4E jmp LookupLoop + + ;;; s->match_start = cur_match; + ;;; best_len = len; + ;;; if (len >= nice_match) break; + ;;; scan_end = *(ushf*)(scan+best_len-1); + + 00000146 8B 5C 24 18 LongerMatch: mov ebx, [nicematch] + 0000014A 89 44 24 1C mov [bestlen], eax + 0000014E 89 4A 70 mov [edx + dsMatchStart], ecx + 00000151 3B C3 cmp eax, ebx + 00000153 7D 2D jge LeaveNow + 00000155 8B 74 24 04 mov esi, [window] + 00000159 03 F0 add esi, eax + 0000015B 89 74 24 08 mov [windowbestlen], esi + 0000015F 0F B7 5C 38 FF movzx ebx, word ptr [edi + eax - 1] + 00000164 8B 7A 40 mov edi, [edx + dsPrev] + 00000167 89 5C 24 0C mov [scanend], ebx + 0000016B 8B 14 24 mov edx, [chainlenwmask] + 0000016E E9 FFFFFF21 jmp LookupLoop + + ;;; Accept the current string, with the maximum possible length. + + 00000173 8B 54 24 38 LenMaximum: mov edx, [deflatestate] + 00000177 C7 44 24 1C mov dword ptr [bestlen], MAX_MATCH + 00000102 + 0000017F 89 4A 70 mov [edx + dsMatchStart], ecx + + ;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + ;;; return s->lookahead; + + 00000182 LeaveNow: + 00000182 8B 54 24 38 mov edx, [deflatestate] + 00000186 8B 5C 24 1C mov ebx, [bestlen] + 0000018A 8B 42 74 mov eax, [edx + dsLookahead] + 0000018D 3B D8 cmp ebx, eax + 0000018F 7F 02 jg LookaheadRet + 00000191 8B C3 mov eax, ebx + 00000193 LookaheadRet: + + ;;; Restore the stack and return from whence we came. + + 00000193 83 C4 24 add esp, LocalVarsSize + 00000196 5B pop ebx + 00000197 5E pop esi + 00000198 5F pop edi + 00000199 5D pop ebp + + 0000019A C3 ret + ; please don't remove this string ! + ; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary! + 0000019B 0D 0A 61 73 6D db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah + 36 38 36 20 77 + 69 74 68 20 6D + 61 73 6D 2C 20 + 6F 70 74 69 6D + 69 73 65 64 20 + 61 73 73 65 6D + 62 6C 79 20 63 + 6F 64 65 20 66 + 72 6F 6D 20 42 + 72 69 61 6E 20 + 52 61 69 74 65 + 72 2C 20 77 72 + 69 74 74 65 6E + 20 31 39 39 38 + 0D 0A + + + IFDEF NOUNDERLINE + ELSE + 000001E8 _longest_match endp + ENDIF + + IFDEF NOUNDERLINE + ELSE + 000001E8 _match_init proc near + 000001E8 C3 ret + 000001E9 _match_init endp + ENDIF + + + 000001E9 _TEXT ends + end + Microsoft (R) Macro Assembler Version 12.00.31101.0 05/22/17 22:38:55 +match686.asm Symbols 2 - 1 + + + + +Segments and Groups: + + N a m e Size Length Align Combine Class + +FLAT . . . . . . . . . . . . . . GROUP +_DATA . . . . . . . . . . . . . 32 Bit 00000000 Para Public 'DATA' +_TEXT . . . . . . . . . . . . . 32 Bit 000001E9 Para Public 'CODE' + + +Procedures, parameters, and locals: + + N a m e Type Value Attr + +_longest_match . . . . . . . . . P Near 00000000 _TEXT Length= 000001E8 Public + LastMatchGood . . . . . . . . L Near 00000025 _TEXT + LookaheadLess . . . . . . . . L Near 0000003D _TEXT + LimitPositive . . . . . . . . L Near 0000006C _TEXT + LookupLoop . . . . . . . . . . L Near 00000094 _TEXT + LoopEntry . . . . . . . . . . L Near 000000AE _TEXT + LoopCmps . . . . . . . . . . . L Near 000000E9 _TEXT + LeaveLoopCmps4 . . . . . . . . L Near 00000102 _TEXT + LeaveLoopCmps . . . . . . . . L Near 00000105 _TEXT + LenLower . . . . . . . . . . . L Near 00000112 _TEXT + LongerMatch . . . . . . . . . L Near 00000146 _TEXT + LenMaximum . . . . . . . . . . L Near 00000173 _TEXT + LeaveNow . . . . . . . . . . . L Near 00000182 _TEXT + LookaheadRet . . . . . . . . . L Near 00000193 _TEXT +_match_init . . . . . . . . . . P Near 000001E8 _TEXT Length= 00000001 Public + + +Symbols: + + N a m e Type Value Attr + +@CodeSize . . . . . . . . . . . Number 00000000h +@DataSize . . . . . . . . . . . Number 00000000h +@Interface . . . . . . . . . . . Number 00000000h +@Model . . . . . . . . . . . . . Number 00000007h +@code . . . . . . . . . . . . . Text _TEXT +@data . . . . . . . . . . . . . Text FLAT +@fardata? . . . . . . . . . . . Text FLAT +@fardata . . . . . . . . . . . . Text FLAT +@stack . . . . . . . . . . . . . Text FLAT +LocalVarsSize . . . . . . . . . Number 00000024h +MAX_MATCH_8_ . . . . . . . . . . Number 00000100h +MAX_MATCH . . . . . . . . . . . Number 00000102h +MIN_LOOKAHEAD . . . . . . . . . Number 00000106h +MIN_MATCH . . . . . . . . . . . Number 00000003h +NbStackAdd . . . . . . . . . . . Number 00000034h +NbStack . . . . . . . . . . . . Number 0000004Ch +adrret . . . . . . . . . . . . . Text dword ptr[esp+NbStack-8] +best_len . . . . . . . . . . . . Text dword ptr [esp+NbStack-36] +bestlen . . . . . . . . . . . . Text esp + 28 +chain_length . . . . . . . . . . Text dword ptr [esp+NbStack-28] +chainlenwmask . . . . . . . . . Text esp + 0 +cur_match . . . . . . . . . . . Text dword ptr[esp+NbStack-0] +curmatch . . . . . . . . . . . . Text esp + 60 +deflatestate . . . . . . . . . . Text esp + 56 +dep_chain_length . . . . . . . . Number 0000007Ch +dep_good_match . . . . . . . . . Number 0000008Ch +dep_lookahead . . . . . . . . . Number 00000074h +dep_match_start . . . . . . . . Number 00000070h +dep_nice_match . . . . . . . . . Number 00000090h +dep_prev_length . . . . . . . . Number 00000078h +dep_prev . . . . . . . . . . . . Number 00000040h +dep_strstart . . . . . . . . . . Number 0000006Ch +dep_w_mask . . . . . . . . . . . Number 00000034h +dep_w_size . . . . . . . . . . . Number 0000002Ch +dep_window . . . . . . . . . . . Number 00000038h +dsGoodMatch . . . . . . . . . . Number 0000008Ch +dsLookahead . . . . . . . . . . Number 00000074h +dsMatchLen . . . . . . . . . . . Number 00000060h +dsMatchStart . . . . . . . . . . Number 00000070h +dsMaxChainLen . . . . . . . . . Number 0000007Ch +dsNiceMatch . . . . . . . . . . Number 00000090h +dsPrevLen . . . . . . . . . . . Number 00000078h +dsPrevMatch . . . . . . . . . . Number 00000064h +dsPrev . . . . . . . . . . . . . Number 00000040h +dsStrStart . . . . . . . . . . . Number 0000006Ch +dsWMask . . . . . . . . . . . . Number 00000034h +dsWSize . . . . . . . . . . . . Number 0000002Ch +dsWindow . . . . . . . . . . . . Number 00000038h +limit . . . . . . . . . . . . . Text dword ptr [esp+NbStack-32] +match_start_ptr . . . . . . . . Text dword ptr [esp+NbStack-56] +match_start . . . . . . . . . . Text dword ptr [esp+NbStack-72] +nice_match . . . . . . . . . . . Text dword ptr [esp+NbStack-60] +nicematch . . . . . . . . . . . Text esp + 24 +prev . . . . . . . . . . . . . . Text dword ptr [esp+NbStack-44] +pushebp . . . . . . . . . . . . Text dword ptr[esp+NbStack-12] +pushebx . . . . . . . . . . . . Text dword ptr[esp+NbStack-24] +pushedi . . . . . . . . . . . . Text dword ptr[esp+NbStack-16] +pushesi . . . . . . . . . . . . Text dword ptr[esp+NbStack-20] +scan_start . . . . . . . . . . . Text word ptr [esp+NbStack-48] +scanalign . . . . . . . . . . . Text esp + 20 +scanend . . . . . . . . . . . . Text esp + 12 +scanstart . . . . . . . . . . . Text esp + 16 +scan . . . . . . . . . . . . . . Text esp + 32 +str_s . . . . . . . . . . . . . Text dword ptr[esp+NbStack-4] +strend . . . . . . . . . . . . . Text dword ptr [esp+NbStack-76] +windowbestlen . . . . . . . . . Text esp + 8 +windowlen . . . . . . . . . . . Text dword ptr [esp+NbStack-68] +window . . . . . . . . . . . . . Text esp + 4 +wmask . . . . . . . . . . . . . Text dword ptr [esp+NbStack-52] +zlib1222add . . . . . . . . . . Number 00000008h + + 0 Warnings + 0 Errors diff --git a/libz/contrib/masmx86/readme.txt b/libz/contrib/masmx86/readme.txt new file mode 100644 index 000000000..3271f720a --- /dev/null +++ b/libz/contrib/masmx86/readme.txt @@ -0,0 +1,27 @@ + +Summary +------- +This directory contains ASM implementations of the functions +longest_match() and inflate_fast(). + + +Use instructions +---------------- +Assemble using MASM, and copy the object files into the zlib source +directory, then run the appropriate makefile, as suggested below. You can +donwload MASM from here: + + http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64 + +You can also get objects files here: + + http://www.winimage.com/zLibDll/zlib124_masm_obj.zip + +Build instructions +------------------ +* With Microsoft C and MASM: +nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj" + +* With Borland C and TASM: +make -f win32/Makefile.bor LOCAL_ZLIB="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj" OBJPA="+match686c.obj+match686.obj+inffas32.obj" + diff --git a/libz/contrib/minizip/Makefile.am b/libz/contrib/minizip/Makefile.am new file mode 100644 index 000000000..d343011eb --- /dev/null +++ b/libz/contrib/minizip/Makefile.am @@ -0,0 +1,45 @@ +lib_LTLIBRARIES = libminizip.la + +if COND_DEMOS +bin_PROGRAMS = miniunzip minizip +endif + +zlib_top_srcdir = $(top_srcdir)/../.. +zlib_top_builddir = $(top_builddir)/../.. + +AM_CPPFLAGS = -I$(zlib_top_srcdir) +AM_LDFLAGS = -L$(zlib_top_builddir) + +if WIN32 +iowin32_src = iowin32.c +iowin32_h = iowin32.h +endif + +libminizip_la_SOURCES = \ + ioapi.c \ + mztools.c \ + unzip.c \ + zip.c \ + ${iowin32_src} + +libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz + +minizip_includedir = $(includedir)/minizip +minizip_include_HEADERS = \ + crypt.h \ + ioapi.h \ + mztools.h \ + unzip.h \ + zip.h \ + ${iowin32_h} + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = minizip.pc + +EXTRA_PROGRAMS = miniunzip minizip + +miniunzip_SOURCES = miniunz.c +miniunzip_LDADD = libminizip.la + +minizip_SOURCES = minizip.c +minizip_LDADD = libminizip.la -lz diff --git a/libz/contrib/minizip/MiniZip64_Changes.txt b/libz/contrib/minizip/MiniZip64_Changes.txt new file mode 100644 index 000000000..13a1bd91a --- /dev/null +++ b/libz/contrib/minizip/MiniZip64_Changes.txt @@ -0,0 +1,6 @@ + +MiniZip 1.1 was derrived from MiniZip at version 1.01f + +Change in 1.0 (Okt 2009) + - **TODO - Add history** + diff --git a/libz/contrib/minizip/MiniZip64_info.txt b/libz/contrib/minizip/MiniZip64_info.txt new file mode 100644 index 000000000..57d715242 --- /dev/null +++ b/libz/contrib/minizip/MiniZip64_info.txt @@ -0,0 +1,74 @@ +MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson + +Introduction +--------------------- +MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html ) + +When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0. +All possible work was done for compatibility. + + +Background +--------------------- +When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64 +support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ ) + +That was used as a starting point. And after that ZIP64 support was added to zip.c +some refactoring and code cleanup was also done. + + +Changed from MiniZip 1.0 to MiniZip 1.1 +--------------------------------------- +* Added ZIP64 support for unzip ( by Even Rouault ) +* Added ZIP64 support for zip ( by Mathias Svensson ) +* Reverted some changed that Even Rouault did. +* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users. +* Added unzip patch for BZIP Compression method (patch create by Daniel Borca) +* Added BZIP Compress method for zip +* Did some refactoring and code cleanup + + +Credits + + Gilles Vollant - Original MiniZip author + Even Rouault - ZIP64 unzip Support + Daniel Borca - BZip Compression method support in unzip + Mathias Svensson - ZIP64 zip support + Mathias Svensson - BZip Compression method support in zip + + Resources + + ZipLayout http://result42.com/projects/ZipFileLayout + Command line tool for Windows that shows the layout and information of the headers in a zip archive. + Used when debugging and validating the creation of zip files using MiniZip64 + + + ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT + Zip File specification + + +Notes. + * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined. + +License +---------------------------------------------------------- + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + +---------------------------------------------------------- + diff --git a/libz/contrib/minizip/configure.ac b/libz/contrib/minizip/configure.ac new file mode 100644 index 000000000..827a4e057 --- /dev/null +++ b/libz/contrib/minizip/configure.ac @@ -0,0 +1,32 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_INIT([minizip], [1.2.8], [bugzilla.redhat.com]) +AC_CONFIG_SRCDIR([minizip.c]) +AM_INIT_AUTOMAKE([foreign]) +LT_INIT + +AC_MSG_CHECKING([whether to build example programs]) +AC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs])) +AM_CONDITIONAL([COND_DEMOS], [test "$enable_demos" = yes]) +if test "$enable_demos" = yes +then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +case "${host}" in + *-mingw* | mingw*) + WIN32="yes" + ;; + *) + ;; +esac +AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) + + +AC_SUBST([HAVE_UNISTD_H], [0]) +AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], []) +AC_CONFIG_FILES([Makefile minizip.pc]) +AC_OUTPUT diff --git a/libz/contrib/minizip/crypt.h b/libz/contrib/minizip/crypt.h new file mode 100644 index 000000000..1e9e8200b --- /dev/null +++ b/libz/contrib/minizip/crypt.h @@ -0,0 +1,131 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(const char* passwd, /* password string */ + unsigned char* buf, /* where to write header */ + int bufSize, + unsigned long* pkeys, + const z_crc_t* pcrc_32_tab, + unsigned long crcForCrypting) +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/libz/contrib/minizip/ioapi.c b/libz/contrib/minizip/ioapi.c new file mode 100644 index 000000000..7f5c191b2 --- /dev/null +++ b/libz/contrib/minizip/ioapi.c @@ -0,0 +1,247 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS))) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#if defined(__APPLE__) || defined(IOAPI_NO_64) +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == MAXU32) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = FOPEN_FUNC((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = FTELLO_FUNC((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/libz/contrib/minizip/ioapi.h b/libz/contrib/minizip/ioapi.h new file mode 100644 index 000000000..8dcbdb06e --- /dev/null +++ b/libz/contrib/minizip/ioapi.h @@ -0,0 +1,208 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif + +#endif + +#include +#include +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef __FreeBSD__ +#define fopen64 fopen +#define ftello64 ftello +#define fseeko64 fseeko +#endif +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + +/* Maximum unsigned 32-bit value used as placeholder for zip64 */ +#define MAXU32 0xffffffff + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libz/contrib/minizip/iowin32.c b/libz/contrib/minizip/iowin32.c new file mode 100644 index 000000000..a46d96c7f --- /dev/null +++ b/libz/contrib/minizip/iowin32.c @@ -0,0 +1,461 @@ +/* iowin32.c -- IO base function header for compress/uncompress .zip + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#include + +#include "zlib.h" +#include "ioapi.h" +#include "iowin32.h" + +#ifndef INVALID_HANDLE_VALUE +#define INVALID_HANDLE_VALUE (0xFFFFFFFF) +#endif + +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + + +#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API))) +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define IOWIN32_USING_WINRT_API 1 +#endif +#endif + +voidpf ZCALLBACK win32_open_file_func OF((voidpf opaque, const char* filename, int mode)); +uLong ZCALLBACK win32_read_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +uLong ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +ZPOS64_T ZCALLBACK win32_tell64_file_func OF((voidpf opaque, voidpf stream)); +long ZCALLBACK win32_seek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +int ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream)); +int ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream)); + +typedef struct +{ + HANDLE hf; + int error; +} WIN32FILE_IOWIN; + + +static void win32_translate_open_mode(int mode, + DWORD* lpdwDesiredAccess, + DWORD* lpdwCreationDisposition, + DWORD* lpdwShareMode, + DWORD* lpdwFlagsAndAttributes) +{ + *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0; + + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + { + *lpdwDesiredAccess = GENERIC_READ; + *lpdwCreationDisposition = OPEN_EXISTING; + *lpdwShareMode = FILE_SHARE_READ; + } + else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + { + *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + *lpdwCreationDisposition = OPEN_EXISTING; + } + else if (mode & ZLIB_FILEFUNC_MODE_CREATE) + { + *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ; + *lpdwCreationDisposition = CREATE_ALWAYS; + } +} + +static voidpf win32_build_iowin(HANDLE hFile) +{ + voidpf ret=NULL; + + if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)) + { + WIN32FILE_IOWIN w32fiow; + w32fiow.hf = hFile; + w32fiow.error = 0; + ret = malloc(sizeof(WIN32FILE_IOWIN)); + + if (ret==NULL) + CloseHandle(hFile); + else + *((WIN32FILE_IOWIN*)ret) = w32fiow; + } + return ret; +} + +voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + +#ifdef IOWIN32_USING_WINRT_API +#ifdef UNICODE + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + { + WCHAR filenameW[FILENAME_MAX + 0x200 + 1]; + MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200); + hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); + } +#endif +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); +#endif + + return win32_build_iowin(hFile); +} + + +voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + +#ifdef IOWIN32_USING_WINRT_API + if ((filename!=NULL) && (dwDesiredAccess != 0)) + { + WCHAR filenameW[FILENAME_MAX + 0x200 + 1]; + MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200); + hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); + } +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); +#endif + + return win32_build_iowin(hFile); +} + + +voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + +#ifdef IOWIN32_USING_WINRT_API + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL); +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); +#endif + + return win32_build_iowin(hFile); +} + + +voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode) +{ + const char* mode_fopen = NULL; + DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ; + HANDLE hFile = NULL; + + win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes); + +#ifdef IOWIN32_USING_WINRT_API +#ifdef UNICODE + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + { + WCHAR filenameW[FILENAME_MAX + 0x200 + 1]; + MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200); + hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL); + } +#endif +#else + if ((filename!=NULL) && (dwDesiredAccess != 0)) + hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); +#endif + + return win32_build_iowin(hFile); +} + + +uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size) +{ + uLong ret=0; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + + if (hFile != NULL) + { + if (!ReadFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + } + } + + return ret; +} + + +uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size) +{ + uLong ret=0; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + + if (hFile != NULL) + { + if (!WriteFile(hFile, buf, size, &ret, NULL)) + { + DWORD dwErr = GetLastError(); + if (dwErr == ERROR_HANDLE_EOF) + dwErr = 0; + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + } + } + + return ret; +} + +static BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos, DWORD dwMoveMethod) +{ +#ifdef IOWIN32_USING_WINRT_API + return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod); +#else + LONG lHigh = pos.HighPart; + DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, FILE_CURRENT); + BOOL fOk = TRUE; + if (dwNewPos == 0xFFFFFFFF) + if (GetLastError() != NO_ERROR) + fOk = FALSE; + if ((newPos != NULL) && (fOk)) + { + newPos->LowPart = dwNewPos; + newPos->HighPart = lHigh; + } + return fOk; +#endif +} + +long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream) +{ + long ret=-1; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + if (hFile != NULL) + { + LARGE_INTEGER pos; + pos.QuadPart = 0; + + if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT)) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=(long)pos.LowPart; + } + return ret; +} + +ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret= (ZPOS64_T)-1; + HANDLE hFile = NULL; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream)->hf; + + if (hFile) + { + LARGE_INTEGER pos; + pos.QuadPart = 0; + + if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT)) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = (ZPOS64_T)-1; + } + else + ret=pos.QuadPart; + } + return ret; +} + + +long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin) +{ + DWORD dwMoveMethod=0xFFFFFFFF; + HANDLE hFile = NULL; + + long ret=-1; + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + dwMoveMethod = FILE_CURRENT; + break; + case ZLIB_FILEFUNC_SEEK_END : + dwMoveMethod = FILE_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + dwMoveMethod = FILE_BEGIN; + break; + default: return -1; + } + + if (hFile != NULL) + { + LARGE_INTEGER pos; + pos.QuadPart = offset; + if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod)) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=0; + } + return ret; +} + +long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin) +{ + DWORD dwMoveMethod=0xFFFFFFFF; + HANDLE hFile = NULL; + long ret=-1; + + if (stream!=NULL) + hFile = ((WIN32FILE_IOWIN*)stream)->hf; + + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + dwMoveMethod = FILE_CURRENT; + break; + case ZLIB_FILEFUNC_SEEK_END : + dwMoveMethod = FILE_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + dwMoveMethod = FILE_BEGIN; + break; + default: return -1; + } + + if (hFile) + { + LARGE_INTEGER pos; + pos.QuadPart = offset; + if (!MySetFilePointerEx(hFile, pos, NULL, FILE_CURRENT)) + { + DWORD dwErr = GetLastError(); + ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr; + ret = -1; + } + else + ret=0; + } + return ret; +} + +int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream) +{ + int ret=-1; + + if (stream!=NULL) + { + HANDLE hFile; + hFile = ((WIN32FILE_IOWIN*)stream) -> hf; + if (hFile != NULL) + { + CloseHandle(hFile); + ret=0; + } + free(stream); + } + return ret; +} + +int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream) +{ + int ret=-1; + if (stream!=NULL) + { + ret = ((WIN32FILE_IOWIN*)stream) -> error; + } + return ret; +} + +void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen_file = win32_open_file_func; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell_file = win32_tell_file_func; + pzlib_filefunc_def->zseek_file = win32_seek_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = win32_open64_file_func; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; + pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} + + +void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; + pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} + + +void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW; + pzlib_filefunc_def->zread_file = win32_read_file_func; + pzlib_filefunc_def->zwrite_file = win32_write_file_func; + pzlib_filefunc_def->ztell64_file = win32_tell64_file_func; + pzlib_filefunc_def->zseek64_file = win32_seek64_file_func; + pzlib_filefunc_def->zclose_file = win32_close_file_func; + pzlib_filefunc_def->zerror_file = win32_error_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/libz/contrib/minizip/iowin32.h b/libz/contrib/minizip/iowin32.h new file mode 100644 index 000000000..0ca0969a7 --- /dev/null +++ b/libz/contrib/minizip/iowin32.h @@ -0,0 +1,28 @@ +/* iowin32.h -- IO base function header for compress/uncompress .zip + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); +void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def)); + +#ifdef __cplusplus +} +#endif diff --git a/libz/contrib/minizip/make_vms.com b/libz/contrib/minizip/make_vms.com new file mode 100644 index 000000000..9ac13a98f --- /dev/null +++ b/libz/contrib/minizip/make_vms.com @@ -0,0 +1,25 @@ +$ if f$search("ioapi.h_orig") .eqs. "" then copy ioapi.h ioapi.h_orig +$ open/write zdef vmsdefs.h +$ copy sys$input: zdef +$ deck +#define unix +#define fill_zlib_filefunc64_32_def_from_filefunc32 fillzffunc64from +#define Write_Zip64EndOfCentralDirectoryLocator Write_Zip64EoDLocator +#define Write_Zip64EndOfCentralDirectoryRecord Write_Zip64EoDRecord +#define Write_EndOfCentralDirectoryRecord Write_EoDRecord +$ eod +$ close zdef +$ copy vmsdefs.h,ioapi.h_orig ioapi.h +$ cc/include=[--]/prefix=all ioapi.c +$ cc/include=[--]/prefix=all miniunz.c +$ cc/include=[--]/prefix=all unzip.c +$ cc/include=[--]/prefix=all minizip.c +$ cc/include=[--]/prefix=all zip.c +$ link miniunz,unzip,ioapi,[--]libz.olb/lib +$ link minizip,zip,ioapi,[--]libz.olb/lib +$ mcr []minizip test minizip_info.txt +$ mcr []miniunz -l test.zip +$ rename minizip_info.txt; minizip_info.txt_old +$ mcr []miniunz test.zip +$ delete test.zip;* +$exit diff --git a/libz/contrib/minizip/miniunz.c b/libz/contrib/minizip/miniunz.c new file mode 100644 index 000000000..3d65401be --- /dev/null +++ b/libz/contrib/minizip/miniunz.c @@ -0,0 +1,660 @@ +/* + miniunz.c + Version 1.1, February 14h, 2010 + sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) +*/ + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#ifdef __APPLE__ +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +# include +# include +#endif + + +#include "unzip.h" + +#define CASESENSITIVITY (0) +#define WRITEBUFFERSIZE (8192) +#define MAXFILENAME (256) + +#ifdef _WIN32 +#define USEWIN32IOAPI +#include "iowin32.h" +#endif +/* + mini unzip, demo of unzip package + + usage : + Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir] + + list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT + if it exists +*/ + + +/* change_file_date : change the date/time of a file + filename : the filename of the file where date/time must be modified + dosdate : the new date at the MSDos format (4 bytes) + tmu_date : the SAME new date at the tm_unz format */ +void change_file_date(filename,dosdate,tmu_date) + const char *filename; + uLong dosdate; + tm_unz tmu_date; +{ +#ifdef _WIN32 + HANDLE hFile; + FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; + + hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE, + 0,NULL,OPEN_EXISTING,0,NULL); + GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); + DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); + LocalFileTimeToFileTime(&ftLocal,&ftm); + SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); + CloseHandle(hFile); +#else +#ifdef unix || __APPLE__ + struct utimbuf ut; + struct tm newdate; + newdate.tm_sec = tmu_date.tm_sec; + newdate.tm_min=tmu_date.tm_min; + newdate.tm_hour=tmu_date.tm_hour; + newdate.tm_mday=tmu_date.tm_mday; + newdate.tm_mon=tmu_date.tm_mon; + if (tmu_date.tm_year > 1900) + newdate.tm_year=tmu_date.tm_year - 1900; + else + newdate.tm_year=tmu_date.tm_year ; + newdate.tm_isdst=-1; + + ut.actime=ut.modtime=mktime(&newdate); + utime(filename,&ut); +#endif +#endif +} + + +/* mymkdir and change_file_date are not 100 % portable + As I don't know well Unix, I wait feedback for the unix portion */ + +int mymkdir(dirname) + const char* dirname; +{ + int ret=0; +#ifdef _WIN32 + ret = _mkdir(dirname); +#elif unix + ret = mkdir (dirname,0775); +#elif __APPLE__ + ret = mkdir (dirname,0775); +#endif + return ret; +} + +int makedir (newdir) + char *newdir; +{ + char *buffer ; + char *p; + int len = (int)strlen(newdir); + + if (len <= 0) + return 0; + + buffer = (char*)malloc(len+1); + if (buffer==NULL) + { + printf("Error allocating memory\n"); + return UNZ_INTERNALERROR; + } + strcpy(buffer,newdir); + + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mymkdir(buffer) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mymkdir(buffer) == -1) && (errno == ENOENT)) + { + printf("couldn't create directory %s\n",buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + +void do_banner() +{ + printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n"); + printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); +} + +void do_help() +{ + printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \ + " -e Extract without pathname (junk paths)\n" \ + " -x Extract with pathname\n" \ + " -v list files\n" \ + " -l list files\n" \ + " -d directory to extract into\n" \ + " -o overwrite files without prompting\n" \ + " -p extract crypted file using password\n\n"); +} + +void Display64BitsSize(ZPOS64_T n, int size_char) +{ + /* to avoid compatibility problem , we do here the conversion */ + char number[21]; + int offset=19; + int pos_string = 19; + number[20]=0; + for (;;) { + number[offset]=(char)((n%10)+'0'); + if (number[offset] != '0') + pos_string=offset; + n/=10; + if (offset==0) + break; + offset--; + } + { + int size_display_string = 19-pos_string; + while (size_char > size_display_string) + { + size_char--; + printf(" "); + } + } + + printf("%s",&number[pos_string]); +} + +int do_list(uf) + unzFile uf; +{ + uLong i; + unz_global_info64 gi; + int err; + + err = unzGetGlobalInfo64(uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + printf(" Length Method Size Ratio Date Time CRC-32 Name\n"); + printf(" ------ ------ ---- ----- ---- ---- ------ ----\n"); + for (i=0;i0) + ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size); + + /* display a '*' if the file is crypted */ + if ((file_info.flag & 1) != 0) + charCrypt='*'; + + if (file_info.compression_method==0) + string_method="Stored"; + else + if (file_info.compression_method==Z_DEFLATED) + { + uInt iLevel=(uInt)((file_info.flag & 0x6)/2); + if (iLevel==0) + string_method="Defl:N"; + else if (iLevel==1) + string_method="Defl:X"; + else if ((iLevel==2) || (iLevel==3)) + string_method="Defl:F"; /* 2:fast , 3 : extra fast*/ + } + else + if (file_info.compression_method==Z_BZIP2ED) + { + string_method="BZip2 "; + } + else + string_method="Unkn. "; + + Display64BitsSize(file_info.uncompressed_size,7); + printf(" %6s%c",string_method,charCrypt); + Display64BitsSize(file_info.compressed_size,7); + printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n", + ratio, + (uLong)file_info.tmu_date.tm_mon + 1, + (uLong)file_info.tmu_date.tm_mday, + (uLong)file_info.tmu_date.tm_year % 100, + (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min, + (uLong)file_info.crc,filename_inzip); + if ((i+1)='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N') && (rep!='A')); + } + + if (rep == 'N') + skip = 1; + + if (rep == 'A') + *popt_overwrite=1; + } + + if ((skip==0) && (err==UNZ_OK)) + { + fout=FOPEN_FUNC(write_filename,"wb"); + /* some zipfile don't contain directory alone before file */ + if ((fout==NULL) && ((*popt_extract_without_path)==0) && + (filename_withoutpath!=(char*)filename_inzip)) + { + char c=*(filename_withoutpath-1); + *(filename_withoutpath-1)='\0'; + makedir(write_filename); + *(filename_withoutpath-1)=c; + fout=FOPEN_FUNC(write_filename,"wb"); + } + + if (fout==NULL) + { + printf("error opening %s\n",write_filename); + } + } + + if (fout!=NULL) + { + printf(" extracting: %s\n",write_filename); + + do + { + err = unzReadCurrentFile(uf,buf,size_buf); + if (err<0) + { + printf("error %d with zipfile in unzReadCurrentFile\n",err); + break; + } + if (err>0) + if (fwrite(buf,err,1,fout)!=1) + { + printf("error in writing extracted file\n"); + err=UNZ_ERRNO; + break; + } + } + while (err>0); + if (fout) + fclose(fout); + + if (err==0) + change_file_date(write_filename,file_info.dosDate, + file_info.tmu_date); + } + + if (err==UNZ_OK) + { + err = unzCloseCurrentFile (uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzCloseCurrentFile\n",err); + } + } + else + unzCloseCurrentFile(uf); /* don't lose the error */ + } + + free(buf); + return err; +} + + +int do_extract(uf,opt_extract_without_path,opt_overwrite,password) + unzFile uf; + int opt_extract_without_path; + int opt_overwrite; + const char* password; +{ + uLong i; + unz_global_info64 gi; + int err; + FILE* fout=NULL; + + err = unzGetGlobalInfo64(uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + + for (i=0;i insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +miniunzip - uncompress and examine ZIP archives +.SH SYNOPSIS +.B miniunzip +.RI [ -exvlo ] +zipfile [ files_to_extract ] [-d tempdir] +.SH DESCRIPTION +.B minizip +is a simple tool which allows the extraction of compressed file +archives in the ZIP format used by the MS-DOS utility PKZIP. It was +written as a demonstration of the +.IR zlib (3) +library and therefore lack many of the features of the +.IR unzip (1) +program. +.SH OPTIONS +A number of options are supported. With the exception of +.BI \-d\ tempdir +these must be supplied before any +other arguments and are: +.TP +.BI \-l\ ,\ \-\-v +List the files in the archive without extracting them. +.TP +.B \-o +Overwrite files without prompting for confirmation. +.TP +.B \-x +Extract files (default). +.PP +The +.I zipfile +argument is the name of the archive to process. The next argument can be used +to specify a single file to extract from the archive. + +Lastly, the following option can be specified at the end of the command-line: +.TP +.BI \-d\ tempdir +Extract the archive in the directory +.I tempdir +rather than the current directory. +.SH SEE ALSO +.BR minizip (1), +.BR zlib (3), +.BR unzip (1). +.SH AUTHOR +This program was written by Gilles Vollant. This manual page was +written by Mark Brown . The -d tempdir option +was added by Dirk Eddelbuettel . diff --git a/libz/contrib/minizip/minizip.1 b/libz/contrib/minizip/minizip.1 new file mode 100644 index 000000000..1154484c1 --- /dev/null +++ b/libz/contrib/minizip/minizip.1 @@ -0,0 +1,46 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH minizip 1 "May 2, 2001" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +minizip - create ZIP archives +.SH SYNOPSIS +.B minizip +.RI [ -o ] +zipfile [ " files" ... ] +.SH DESCRIPTION +.B minizip +is a simple tool which allows the creation of compressed file archives +in the ZIP format used by the MS-DOS utility PKZIP. It was written as +a demonstration of the +.IR zlib (3) +library and therefore lack many of the features of the +.IR zip (1) +program. +.SH OPTIONS +The first argument supplied is the name of the ZIP archive to create or +.RI -o +in which case it is ignored and the second argument treated as the +name of the ZIP file. If the ZIP file already exists it will be +overwritten. +.PP +Subsequent arguments specify a list of files to place in the ZIP +archive. If none are specified then an empty archive will be created. +.SH SEE ALSO +.BR miniunzip (1), +.BR zlib (3), +.BR zip (1). +.SH AUTHOR +This program was written by Gilles Vollant. This manual page was +written by Mark Brown . + diff --git a/libz/contrib/minizip/minizip.c b/libz/contrib/minizip/minizip.c new file mode 100644 index 000000000..4288962ec --- /dev/null +++ b/libz/contrib/minizip/minizip.c @@ -0,0 +1,520 @@ +/* + minizip.c + Version 1.1, February 14h, 2010 + sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) +*/ + + +#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#ifdef __APPLE__ +// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions +#define FOPEN_FUNC(filename, mode) fopen(filename, mode) +#define FTELLO_FUNC(stream) ftello(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) +#else +#define FOPEN_FUNC(filename, mode) fopen64(filename, mode) +#define FTELLO_FUNC(stream) ftello64(stream) +#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) +#endif + + + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include +#else +# include +# include +# include +# include +#endif + +#include "zip.h" + +#ifdef _WIN32 + #define USEWIN32IOAPI + #include "iowin32.h" +#endif + + + +#define WRITEBUFFERSIZE (16384) +#define MAXFILENAME (256) + +#ifdef _WIN32 +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret = 0; + { + FILETIME ftLocal; + HANDLE hFind; + WIN32_FIND_DATAA ff32; + + hFind = FindFirstFileA(f,&ff32); + if (hFind != INVALID_HANDLE_VALUE) + { + FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); + FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); + FindClose(hFind); + ret = 1; + } + } + return ret; +} +#else +#ifdef unix || __APPLE__ +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + int ret=0; + struct stat s; /* results of stat() */ + struct tm* filedate; + time_t tm_t=0; + + if (strcmp(f,"-")!=0) + { + char name[MAXFILENAME+1]; + int len = strlen(f); + if (len > MAXFILENAME) + len = MAXFILENAME; + + strncpy(name, f,MAXFILENAME-1); + /* strncpy doesnt append the trailing NULL, of the string is too long. */ + name[ MAXFILENAME ] = '\0'; + + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (stat(name,&s)==0) + { + tm_t = s.st_mtime; + ret = 1; + } + } + filedate = localtime(&tm_t); + + tmzip->tm_sec = filedate->tm_sec; + tmzip->tm_min = filedate->tm_min; + tmzip->tm_hour = filedate->tm_hour; + tmzip->tm_mday = filedate->tm_mday; + tmzip->tm_mon = filedate->tm_mon ; + tmzip->tm_year = filedate->tm_year; + + return ret; +} +#else +uLong filetime(f, tmzip, dt) + char *f; /* name of file to get info on */ + tm_zip *tmzip; /* return value: access, modific. and creation times */ + uLong *dt; /* dostime */ +{ + return 0; +} +#endif +#endif + + + + +int check_exist_file(filename) + const char* filename; +{ + FILE* ftestexist; + int ret = 1; + ftestexist = FOPEN_FUNC(filename,"rb"); + if (ftestexist==NULL) + ret = 0; + else + fclose(ftestexist); + return ret; +} + +void do_banner() +{ + printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n"); + printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n"); +} + +void do_help() +{ + printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \ + " -o Overwrite existing file.zip\n" \ + " -a Append to existing file.zip\n" \ + " -0 Store only\n" \ + " -1 Compress faster\n" \ + " -9 Compress better\n\n" \ + " -j exclude path. store only the file name.\n\n"); +} + +/* calculate the CRC32 of a file, + because to encrypt a file, we need known the CRC32 of the file before */ +int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc) +{ + unsigned long calculate_crc=0; + int err=ZIP_OK; + FILE * fin = FOPEN_FUNC(filenameinzip,"rb"); + + unsigned long size_read = 0; + unsigned long total_read = 0; + if (fin==NULL) + { + err = ZIP_ERRNO; + } + + if (err == ZIP_OK) + do + { + err = ZIP_OK; + size_read = (int)fread(buf,1,size_buf,fin); + if (size_read < size_buf) + if (feof(fin)==0) + { + printf("error in reading %s\n",filenameinzip); + err = ZIP_ERRNO; + } + + if (size_read>0) + calculate_crc = crc32(calculate_crc,buf,size_read); + total_read += size_read; + + } while ((err == ZIP_OK) && (size_read>0)); + + if (fin) + fclose(fin); + + *result_crc=calculate_crc; + printf("file %s crc %lx\n", filenameinzip, calculate_crc); + return err; +} + +int isLargeFile(const char* filename) +{ + int largeFile = 0; + ZPOS64_T pos = 0; + FILE* pFile = FOPEN_FUNC(filename, "rb"); + + if(pFile != NULL) + { + int n = FSEEKO_FUNC(pFile, 0, SEEK_END); + pos = FTELLO_FUNC(pFile); + + printf("File : %s is %lld bytes\n", filename, pos); + + if(pos >= 0xffffffff) + largeFile = 1; + + fclose(pFile); + } + + return largeFile; +} + +int main(argc,argv) + int argc; + char *argv[]; +{ + int i; + int opt_overwrite=0; + int opt_compress_level=Z_DEFAULT_COMPRESSION; + int opt_exclude_path=0; + int zipfilenamearg = 0; + char filename_try[MAXFILENAME+16]; + int zipok; + int err=0; + int size_buf=0; + void* buf=NULL; + const char* password=NULL; + + + do_banner(); + if (argc==1) + { + do_help(); + return 0; + } + else + { + for (i=1;i='0') && (c<='9')) + opt_compress_level = c-'0'; + if ((c=='j') || (c=='J')) + opt_exclude_path = 1; + + if (((c=='p') || (c=='P')) && (i+1='a') && (rep<='z')) + rep -= 0x20; + } + while ((rep!='Y') && (rep!='N') && (rep!='A')); + if (rep=='N') + zipok = 0; + if (rep=='A') + opt_overwrite = 2; + } + } + + if (zipok==1) + { + zipFile zf; + int errclose; +# ifdef USEWIN32IOAPI + zlib_filefunc64_def ffunc; + fill_win32_filefunc64A(&ffunc); + zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc); +# else + zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0); +# endif + + if (zf == NULL) + { + printf("error opening %s\n",filename_try); + err= ZIP_ERRNO; + } + else + printf("creating %s\n",filename_try); + + for (i=zipfilenamearg+1;(i='0') || (argv[i][1]<='9'))) && + (strlen(argv[i]) == 2))) + { + FILE * fin; + int size_read; + const char* filenameinzip = argv[i]; + const char *savefilenameinzip; + zip_fileinfo zi; + unsigned long crcFile=0; + int zip64 = 0; + + zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = + zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; + zi.dosDate = 0; + zi.internal_fa = 0; + zi.external_fa = 0; + filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); + +/* + err = zipOpenNewFileInZip(zf,filenameinzip,&zi, + NULL,0,NULL,0,NULL / * comment * /, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level); +*/ + if ((password != NULL) && (err==ZIP_OK)) + err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); + + zip64 = isLargeFile(filenameinzip); + + /* The path name saved, should not include a leading slash. */ + /*if it did, windows/xp and dynazip couldn't read the zip file. */ + savefilenameinzip = filenameinzip; + while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' ) + { + savefilenameinzip++; + } + + /*should the zip file contain any path at all?*/ + if( opt_exclude_path ) + { + const char *tmpptr; + const char *lastslash = 0; + for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++) + { + if( *tmpptr == '\\' || *tmpptr == '/') + { + lastslash = tmpptr; + } + } + if( lastslash != NULL ) + { + savefilenameinzip = lastslash+1; // base filename follows last slash. + } + } + + /**/ + err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi, + NULL,0,NULL,0,NULL /* comment*/, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level,0, + /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + password,crcFile, zip64); + + if (err != ZIP_OK) + printf("error in opening %s in zipfile\n",filenameinzip); + else + { + fin = FOPEN_FUNC(filenameinzip,"rb"); + if (fin==NULL) + { + err=ZIP_ERRNO; + printf("error in opening %s for reading\n",filenameinzip); + } + } + + if (err == ZIP_OK) + do + { + err = ZIP_OK; + size_read = (int)fread(buf,1,size_buf,fin); + if (size_read < size_buf) + if (feof(fin)==0) + { + printf("error in reading %s\n",filenameinzip); + err = ZIP_ERRNO; + } + + if (size_read>0) + { + err = zipWriteInFileInZip (zf,buf,size_read); + if (err<0) + { + printf("error in writing %s in the zipfile\n", + filenameinzip); + } + + } + } while ((err == ZIP_OK) && (size_read>0)); + + if (fin) + fclose(fin); + + if (err<0) + err=ZIP_ERRNO; + else + { + err = zipCloseFileInZip(zf); + if (err!=ZIP_OK) + printf("error in closing %s in the zipfile\n", + filenameinzip); + } + } + } + errclose = zipClose(zf,NULL); + if (errclose != ZIP_OK) + printf("error in closing %s\n",filename_try); + } + else + { + do_help(); + } + + free(buf); + return 0; +} diff --git a/libz/contrib/minizip/minizip.pc.in b/libz/contrib/minizip/minizip.pc.in new file mode 100644 index 000000000..69b5b7fdc --- /dev/null +++ b/libz/contrib/minizip/minizip.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/minizip + +Name: minizip +Description: Minizip zip file manipulation library +Requires: +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lminizip +Libs.private: -lz +Cflags: -I${includedir} diff --git a/libz/contrib/minizip/mztools.c b/libz/contrib/minizip/mztools.c new file mode 100644 index 000000000..96891c2e0 --- /dev/null +++ b/libz/contrib/minizip/mztools.c @@ -0,0 +1,291 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +/* Code */ +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#define READ_8(adr) ((unsigned char)*(adr)) +#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) +#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) + +#define WRITE_8(buff, n) do { \ + *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ +} while(0) +#define WRITE_16(buff, n) do { \ + WRITE_8((unsigned char*)(buff), n); \ + WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ +} while(0) +#define WRITE_32(buff, n) do { \ + WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ + WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ +} while(0) + +extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) +const char* file; +const char* fileOut; +const char* fileOutTmp; +uLong* nRecovered; +uLong* bytesRecovered; +{ + int err = Z_OK; + FILE* fpZip = fopen(file, "rb"); + FILE* fpOut = fopen(fileOut, "wb"); + FILE* fpOutCD = fopen(fileOutTmp, "wb"); + if (fpZip != NULL && fpOut != NULL) { + int entries = 0; + uLong totalBytes = 0; + char header[30]; + char filename[1024]; + char extra[1024]; + int offset = 0; + int offsetCD = 0; + while ( fread(header, 1, 30, fpZip) == 30 ) { + int currentOffset = offset; + + /* File entry */ + if (READ_32(header) == 0x04034b50) { + unsigned int version = READ_16(header + 4); + unsigned int gpflag = READ_16(header + 6); + unsigned int method = READ_16(header + 8); + unsigned int filetime = READ_16(header + 10); + unsigned int filedate = READ_16(header + 12); + unsigned int crc = READ_32(header + 14); /* crc */ + unsigned int cpsize = READ_32(header + 18); /* compressed size */ + unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ + unsigned int fnsize = READ_16(header + 26); /* file name length */ + unsigned int extsize = READ_16(header + 28); /* extra field length */ + filename[0] = extra[0] = '\0'; + + /* Header */ + if (fwrite(header, 1, 30, fpOut) == 30) { + offset += 30; + } else { + err = Z_ERRNO; + break; + } + + /* Filename */ + if (fnsize > 0) { + if (fnsize < sizeof(filename)) { + if (fread(filename, 1, fnsize, fpZip) == fnsize) { + if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { + offset += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (extsize < sizeof(extra)) { + if (fread(extra, 1, extsize, fpZip) == extsize) { + if (fwrite(extra, 1, extsize, fpOut) == extsize) { + offset += extsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } + + /* Data */ + { + int dataSize = cpsize; + if (dataSize == 0) { + dataSize = uncpsize; + } + if (dataSize > 0) { + char* data = malloc(dataSize); + if (data != NULL) { + if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { + if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { + offset += dataSize; + totalBytes += dataSize; + } else { + err = Z_ERRNO; + } + } else { + err = Z_ERRNO; + } + free(data); + if (err != Z_OK) { + break; + } + } else { + err = Z_MEM_ERROR; + break; + } + } + } + + /* Central directory entry */ + { + char header[46]; + char* comment = ""; + int comsize = (int) strlen(comment); + WRITE_32(header, 0x02014b50); + WRITE_16(header + 4, version); + WRITE_16(header + 6, version); + WRITE_16(header + 8, gpflag); + WRITE_16(header + 10, method); + WRITE_16(header + 12, filetime); + WRITE_16(header + 14, filedate); + WRITE_32(header + 16, crc); + WRITE_32(header + 20, cpsize); + WRITE_32(header + 24, uncpsize); + WRITE_16(header + 28, fnsize); + WRITE_16(header + 30, extsize); + WRITE_16(header + 32, comsize); + WRITE_16(header + 34, 0); /* disk # */ + WRITE_16(header + 36, 0); /* int attrb */ + WRITE_32(header + 38, 0); /* ext attrb */ + WRITE_32(header + 42, currentOffset); + /* Header */ + if (fwrite(header, 1, 46, fpOutCD) == 46) { + offsetCD += 46; + + /* Filename */ + if (fnsize > 0) { + if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { + offsetCD += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { + offsetCD += extsize; + } else { + err = Z_ERRNO; + break; + } + } + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { + offsetCD += comsize; + } else { + err = Z_ERRNO; + break; + } + } + + + } else { + err = Z_ERRNO; + break; + } + } + + /* Success */ + entries++; + + } else { + break; + } + } + + /* Final central directory */ + { + int entriesZip = entries; + char header[22]; + char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; + int comsize = (int) strlen(comment); + if (entriesZip > 0xffff) { + entriesZip = 0xffff; + } + WRITE_32(header, 0x06054b50); + WRITE_16(header + 4, 0); /* disk # */ + WRITE_16(header + 6, 0); /* disk # */ + WRITE_16(header + 8, entriesZip); /* hack */ + WRITE_16(header + 10, entriesZip); /* hack */ + WRITE_32(header + 12, offsetCD); /* size of CD */ + WRITE_32(header + 16, offset); /* offset to CD */ + WRITE_16(header + 20, comsize); /* comment */ + + /* Header */ + if (fwrite(header, 1, 22, fpOutCD) == 22) { + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { + err = Z_ERRNO; + } + } + + } else { + err = Z_ERRNO; + } + } + + /* Final merge (file + central directory) */ + fclose(fpOutCD); + if (err == Z_OK) { + fpOutCD = fopen(fileOutTmp, "rb"); + if (fpOutCD != NULL) { + int nRead; + char buffer[8192]; + while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { + if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { + err = Z_ERRNO; + break; + } + } + fclose(fpOutCD); + } + } + + /* Close */ + fclose(fpZip); + fclose(fpOut); + + /* Wipe temporary file */ + (void)remove(fileOutTmp); + + /* Number of recovered entries */ + if (err == Z_OK) { + if (nRecovered != NULL) { + *nRecovered = entries; + } + if (bytesRecovered != NULL) { + *bytesRecovered = totalBytes; + } + } + } else { + err = Z_STREAM_ERROR; + } + return err; +} diff --git a/libz/contrib/minizip/mztools.h b/libz/contrib/minizip/mztools.h new file mode 100644 index 000000000..a49a426ec --- /dev/null +++ b/libz/contrib/minizip/mztools.h @@ -0,0 +1,37 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +#ifndef _zip_tools_H +#define _zip_tools_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#include "unzip.h" + +/* Repair a ZIP file (missing central directory) + file: file to recover + fileOut: output file after recovery + fileOutTmp: temporary file name used for recovery +*/ +extern int ZEXPORT unzRepair(const char* file, + const char* fileOut, + const char* fileOutTmp, + uLong* nRecovered, + uLong* bytesRecovered); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/libz/contrib/minizip/unzip.c b/libz/contrib/minizip/unzip.c new file mode 100644 index 000000000..909350435 --- /dev/null +++ b/libz/contrib/minizip/unzip.c @@ -0,0 +1,2125 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + + ------------------------------------------------------------------------------------ + Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of + compatibility with older software. The following is from the original crypt.c. + Code woven in by Terry Thorsen 1/2003. + + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + ------------------------------------------------------------------------------------ + + Changes in unzip.c + + 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos + 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz* + 2007-2008 - Even Rouault - Remove old C style function prototypes + 2007-2008 - Even Rouault - Add unzip support for ZIP64 + + Copyright (C) 2007-2008 Even Rouault + + + Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again). + Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G + should only read the compressed/uncompressed size from the Zip64 format if + the size from normal header was 0xFFFFFFFF + Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant + Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required) + Patch created by Daniel Borca + + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + + Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson + +*/ + + +#include +#include +#include + +#ifndef NOUNCRYPT + #define NOUNCRYPT +#endif + +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info64_internal_s +{ + ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ +} unz_file_info64_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip64_read_info_s; + + +/* unz64_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; + + int isZip64; + +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const z_crc_t* pcrc_32_tab; +# endif +} unz64_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unz64local_getByte OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unz64local_getShort OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX) +{ + uLong x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unz64local_getLong64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX)); + + +local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T *pX) +{ + ZPOS64_T x ; + int i = 0; + int err; + + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<8; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<16; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<24; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<32; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<40; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<48; + + if (err==UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); + x |= ((ZPOS64_T)i)<<56; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, + const char* fileName2, + int iCaseSensitivity) + +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); +local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Locate the Central directory 64 of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T unz64local_SearchCentralDir64 OF(( + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); + +local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) + return 0; + + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) + return 0; + + if (uL != 0x06064b50) + return 0; + + return relativeOffset; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +local unzFile unzOpenInternal (const void *path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) +{ + unz64_s us; + unz64_s *s; + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + + + + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; + + us.isZip64 = 1; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + us.isZip64 = 0; + + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.gi.number_entry = uL; + + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + number_entry_CD = uL; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.size_central_dir = uL; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + us.offset_central_dir = uL; + + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + } + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +{ + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; +} +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +{ + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unz64local_GetCurrentFileInfoInternal (unzFile file, + unz_file_info64 *pfile_info, + unz_file_info64_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + uLong uL; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.compressed_size = uL; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info.uncompressed_size = uL; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + file_info_internal.offset_curfile = uL; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + // Read extrafield + if ((err==UNZ_OK) && (extraField!=NULL)) + { + ZPOS64_T uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; + + + if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; + + if (lSeek!=0) + { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + while(acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) + err=UNZ_ERRNO; + + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; + + if(file_info.uncompressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.compressed_size == MAXU32) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info_internal.offset_curfile == MAXU32) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + } + + if(file_info.disk_num_start == MAXU32) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) + err=UNZ_ERRNO; + } + + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) + err=UNZ_ERRNO; + } + + acc += 2 + 2 + dataSize; + } + } + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, + unz_file_info64 * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, + unz_file_info * pfile_info, + char * szFileName, uLong fileNameBufferSize, + void *extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) +{ + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); + if ((err==UNZ_OK) && (pfile_info != NULL)) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; + + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; + + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; + + pfile_info->tmu_date = file_info64.tmu_date, + + + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + + } + return err; +} +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (unzFile file) +{ + int err=UNZ_OK; + unz64_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (unzFile file) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +{ + unz64_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo64(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; // offset in file + ZPOS64_T num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +{ + unz64_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file,&file_pos64); + if (err==UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; +} + +extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) +{ + unz64_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos) +{ + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; + + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file,&file_pos64); +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, + ZPOS64_T * poffset_local_extrafield, + uInt * psize_local_extrafield) +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, + int* level, int raw, const char* password) +{ + int err=UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && +/* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method!=Z_BZIP2ED) && +/* #endif */ + (s->cur_file_info.compression_method!=Z_DEFLATED)) + + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->total_out_64=0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw=1; +#endif + } + else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s=(unz64_s*)file; + if (file==NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info==NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; +} + +/** Addition for GDAL : END */ + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +{ + int err=UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if (pfile_in_zip_read_info->read_buffer == NULL) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; + + err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err==BZ_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + ZPOS64_T uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + +extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +{ + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return (ZPOS64_T)-1; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return (ZPOS64_T)-1; + + return pfile_in_zip_read_info->total_out_64; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (unzFile file) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +{ + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (unzFile file) +{ + int err=UNZ_OK; + + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); +#ifdef HAVE_BZIP2 + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); +#endif + + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +{ + unz64_s* s; + uLong uReadThis ; + if (file==NULL) + return (int)UNZ_PARAMERROR; + s=(unz64_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) +{ + unz64_s* s; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + s=(unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern uLong ZEXPORT unzGetOffset (unzFile file) +{ + ZPOS64_T offset64; + + if (file==NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; +} + +extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) +{ + unz64_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz64_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +{ + return unzSetOffset64(file,pos); +} diff --git a/libz/contrib/minizip/unzip.h b/libz/contrib/minizip/unzip.h new file mode 100644 index 000000000..2104e3915 --- /dev/null +++ b/libz/contrib/minizip/unzip.h @@ -0,0 +1,437 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------------- + + Changes + + See header of unzip64.c + +*/ + +#ifndef _unz64_H +#define _unz64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info64_s +{ + ZPOS64_T number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info64; + +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info64_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info64; + +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +extern unzFile ZEXPORT unzOpen64 OF((const void *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + the "64" function take a const void* pointer, because the path is just the + value passed to the open64_file_func callback. + Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path + is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* + does not describe the reality +*/ + + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unz64Open, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzCloseCurrentFile before call unzClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); + +extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +typedef struct unz64_file_pos_s +{ + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ +} unz64_file_pos; + +extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + + +/** Addition for GDAL : START */ + +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + +/** Addition for GDAL : END */ + + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); + +extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz64_H */ diff --git a/libz/contrib/minizip/zip.c b/libz/contrib/minizip/zip.c new file mode 100644 index 000000000..ea54853e8 --- /dev/null +++ b/libz/contrib/minizip/zip.c @@ -0,0 +1,2007 @@ +/* zip.c -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + Oct-2009 - Mathias Svensson - Remove old C style function prototypes + Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives + Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. + Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data + It is used when recreting zip archive with RAW when deleting items from a zip. + ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. + Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + +*/ + + +#include +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (64*1024) //(16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + + +// NOT sure that this work on ALL platform +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x6064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + ZPOS64_T pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralExtra; + uLong size_centralheader; /* size of the central header for cur file */ + uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; + int encrypt; + int zip64; /* Add ZIP64 extened information in the extra field */ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; +#ifndef NOCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const z_crc_t* pcrc_32_tab; + int crypt_header_size; +#endif +} curfile64_info; + +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile64_info ci; /* info on the file curretly writing */ + + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T add_position_when_writting_offset; + ZPOS64_T number_entry; + +#ifndef NO_ADDFILEINEXISTINGZIP + char *globalcomment; +#endif + +} zip64_internal; + + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(linkedlist_datablock_internal* ldi) +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(linkedlist_data* ll) +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(linkedlist_data* ll) +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + + +/****************************************************************************/ + +#ifndef NO_ADDFILEINEXISTINGZIP +/* =========================================================================== + Inputs a long in LSB order to the given file + nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) +*/ + +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +{ + unsigned char buf[8]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } + + if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } +} + +/****************************************************************************/ + + +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) +{ + uLong year = (uLong)ptm->tm_year; + if (year>=1980) + year-=1980; + else if (year>=80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); + +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return ZIP_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); + + +local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) +{ + ZPOS64_T x; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<24; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<32; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<40; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<48; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<56; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + + return err; +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* +Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before +the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + { + // Signature "0x07064b50" Zip64 end of central directory locater + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + } + + if (uPosFound!=0) + break; + } + + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) + return 0; + + /* total number of disks */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto Zip64 end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' + return 0; + + return relativeOffset; +} + +int LoadCentralDirectoryRecord(zip64_internal* pziinit) +{ + int err=ZIP_OK; + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory */ + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry; + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + uLong VersionMadeBy; + uLong VersionNeeded; + uLong size_comment; + + int hasZIP64Record = 0; + + // check first if we find a ZIP64 record + central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); + if(central_pos > 0) + { + hasZIP64Record = 1; + } + else if(central_pos == 0) + { + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); + } + +/* disable to allow appending to empty ZIP archive + if (central_pos==0) + err=ZIP_ERRNO; +*/ + + if(hasZIP64Record) + { + ZPOS64_T sizeEndOfCentralDirectory; + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* size of zip64 end of central directory record */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version made by */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version needed to extract */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + // TODO.. + // read the comment from the standard central header. + size_comment = 0; + } + else + { + // Read End of central Directory info + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + number_entry = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry = uL; + + /* total number of entries in the central dir */ + number_entry_CD = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry_CD = uL; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + size_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + size_central_dir = uL; + + /* offset of start of central directory with respect to the starting disk number */ + offset_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + offset_central_dir = uL; + + + /* zipfile global comment length */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) + err=ZIP_ERRNO; + } + + if ((central_posz_filefunc, pziinit->filestream); + return ZIP_ERRNO; + } + + if (size_comment>0) + { + pziinit->globalcomment = (char*)ALLOC(size_comment+1); + if (pziinit->globalcomment) + { + size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); + pziinit->globalcomment[size_comment]=0; + } + } + + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); + pziinit->add_position_when_writting_offset = byte_before_the_zipfile; + + { + ZPOS64_T size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + while ((size_central_dir_to_read>0) && (err==ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); + + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + pziinit->begin_pos = byte_before_the_zipfile; + pziinit->number_entry = number_entry_CD; + + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + return err; +} + + +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + + +/************************************************************/ +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +{ + zip64_internal ziinit; + zip64_internal* zi; + int err=ZIP_OK; + + ziinit.z_filefunc.zseek32_file = NULL; + ziinit.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); + else + ziinit.z_filefunc = *pzlib_filefunc64_32_def; + + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) + return NULL; + + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + + + + zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); + if (zi==NULL) + { + ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); + return NULL; + } + + /* now we add file in a zipfile */ +# ifndef NO_ADDFILEINEXISTINGZIP + ziinit.globalcomment = NULL; + if (append == APPEND_STATUS_ADDINZIP) + { + // Read and Cache Central Directory Records + err = LoadCentralDirectoryRecord(&ziinit); + } + + if (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { +# ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } +} + +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +{ + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +{ + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + + + +extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +{ + return zipOpen3((const void*)pathname,append,NULL,NULL); +} + +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +{ + return zipOpen3(pathname,append,NULL,NULL); +} + +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +{ + /* write the local header */ + int err; + uInt size_filename = (uInt)strlen(filename); + uInt size_extrafield = size_extrafield_local; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); + + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); + + // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ + } + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); + + if(zi->ci.zip64) + { + size_extrafield += 20; + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); + + if ((err==ZIP_OK) && (size_filename > 0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) + err = ZIP_ERRNO; + } + + if ((err==ZIP_OK) && (size_extrafield_local > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) + err = ZIP_ERRNO; + } + + + if ((err==ZIP_OK) && (zi->ci.zip64)) + { + // write the Zip64 extended info + short HeaderID = 1; + short DataSize = 16; + ZPOS64_T CompressedSize = 0; + ZPOS64_T UncompressedSize = 0; + + // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); + } + + return err; +} + +/* + NOTE. + When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped + before calling this function it can be done with zipRemoveExtraInfoBlock + + It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize + unnecessary allocations. + */ +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) +{ + zip64_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + +# ifdef NOCRYPT + (crcForCrypting); + if (password != NULL) + return ZIP_PARAMERROR; +# endif + + if (file == NULL) + return ZIP_PARAMERROR; + +#ifdef HAVE_BZIP2 + if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) + return ZIP_PARAMERROR; +#else + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; +#endif + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); + + size_filename = (uInt)strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + } + + zi->ci.flag = flagBase; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if (level==2) + zi->ci.flag |= 4; + if (level==1) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; + zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data + + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + + zi->ci.size_centralExtra = size_extrafield_global; + zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + if(zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + zi->ci.zip64 = zip64; + zi->ci.totalCompressedData = 0; + zi->ci.totalUncompressedData = 0; + zi->ci.pos_zip64extrainfo = 0; + + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + +#ifdef HAVE_BZIP2 + zi->ci.bstream.avail_in = (uInt)0; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + zi->ci.bstream.total_in_hi32 = 0; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_out_hi32 = 0; + zi->ci.bstream.total_out_lo32 = 0; +#endif + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; + +#ifdef HAVE_BZIP2 + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +#else + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +#endif + { + if(zi->ci.method == Z_DEFLATED) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + if (windowBits>0) + windowBits = -windowBits; + + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + + if (err==Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } + else if(zi->ci.method == Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + // Init BZip stuff here + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; + + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); + if(err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; +#endif + } + + } + +# ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +local int zip64FlushWriteBuffer(zip64_internal* zi) +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { +#ifndef NOCRYPT + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +#endif + } + + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED) + { + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; + } + else +#endif + { + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; + } + + + zi->ci.pos_in_buffered_data = 0; + + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +{ + zip64_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + { + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; + + while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) + { + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + + + if(err != BZ_RUN_OK) + break; + + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; +// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; + } + } + + if(err == BZ_RUN_OK) + err = ZIP_OK; + } + else +#endif + { + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + if(uTotalOutBefore > zi->ci.stream.total_out) + { + int bBreak = 0; + bBreak++; + } + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + }// while(...) + } + + return err; +} + +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +{ + return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); +} + +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +{ + zip64_internal* zi; + ZPOS64_T compressed_size; + uLong invalidValue = 0xffffffff; + short datasize = 0; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { +#ifdef HAVE_BZIP2 + err = BZ_FINISH_OK; + while (err==BZ_FINISH_OK) + { + uLong uTotalOutBefore; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.bstream.total_out_lo32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if(err == BZ_STREAM_END) + err = Z_STREAM_END; + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); + } + + if(err == BZ_FINISH_OK) + err = ZIP_OK; +#endif + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + { + if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) + err = ZIP_ERRNO; + } + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } +#ifdef HAVE_BZIP2 + else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err==ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } +#endif + + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = zi->ci.totalUncompressedData; + } + compressed_size = zi->ci.totalCompressedData; + +# ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +# endif + + // update Current Item crc and sizes, + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { + /*version Made by*/ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); + /*version needed*/ + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); + + } + + zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + + + if(compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ + + /// set internal file attributes field + if (zi->ci.stream.data_type == Z_ASCII) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); + + if(uncompressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + + // Add ZIP64 extra info field for uncompressed size + if(uncompressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for compressed size + if(compressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for relative offset to local file header of current file + if(zi->ci.pos_local_header >= 0xffffffff) + datasize += 8; + + if(datasize > 0) + { + char* p = NULL; + + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + { + // we can not write more data to the buffer that we have room for. + return ZIP_BADZIPFILE; + } + + p = zi->ci.central_header + zi->ci.size_centralheader; + + // Add Extra Information Header for 'ZIP64 information' + zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); // DataSize + p += 2; + + if(uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } + + if(compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } + + if(zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } + + // Update how much extra free space we got in the memory buffer + // and increase the centralheader size so the new ZIP64 fields are included + // ( 4 below is the size of HeaderID and DataSize field ) + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; + + // Update the extra info size field + zi->ci.size_centralExtra += datasize + 4; + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); + } + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); + + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + // Update the LocalFileHeader with the new values. + + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + + if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff ) + { + if(zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + else + err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal + } + else + { + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + } + + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipCloseFileInZip (zipFile file) +{ + return zipCloseFileInZipRaw (file,0,0); +} + +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) +{ + int err = ZIP_OK; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); + + /*num disks*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + /*relative offset*/ + if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); + + /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); + + return err; +} + +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + uLong Zip64DataSize = 44; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? + + if (err==ZIP_OK) /* version made by */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* version needed */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); + } + return err; +} +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + /*signature*/ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + { + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + } + + if (err==ZIP_OK) /* total number of entries in the central dir */ + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + { + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); + } + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); + } + + return err; +} + +int Write_GlobalComment(zip64_internal* zi, const char* global_comment) +{ + int err = ZIP_OK; + uInt size_global_comment = 0; + + if(global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + + if (err == ZIP_OK && size_global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + } + return err; +} + +extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +{ + zip64_internal* zi; + int err = 0; + uLong size_centraldir = 0; + ZPOS64_T centraldir_pos_inzip; + ZPOS64_T pos; + + if (file == NULL) + return ZIP_PARAMERROR; + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + +#ifndef NO_ADDFILEINEXISTINGZIP + if (global_comment==NULL) + global_comment = zi->globalcomment; +#endif + + centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + err = ZIP_ERRNO; + } + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_linkedlist(&(zi->central_dir)); + + pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) + { + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + } + + if (err==ZIP_OK) + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + if(err == ZIP_OK) + err = Write_GlobalComment(zi, global_comment); + + if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(zi->globalcomment); +#endif + TRYFREE(zi); + + return err; +} + +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) +{ + char* p = pData; + int size = 0; + char* pNewHeader; + char* pTmp; + short header; + short dataSize; + + int retVal = ZIP_OK; + + if(pData == NULL || *dataLen < 4) + return ZIP_PARAMERROR; + + pNewHeader = (char*)ALLOC(*dataLen); + pTmp = pNewHeader; + + while(p < (pData + *dataLen)) + { + header = *(short*)p; + dataSize = *(((short*)p)+1); + + if( header == sHeader ) // Header found. + { + p += dataSize + 4; // skip it. do not copy to temp buffer + } + else + { + // Extra Info block should not be removed, So copy it to the temp buffer. + memcpy(pTmp, p, dataSize + 4); + p += dataSize + 4; + size += dataSize + 4; + } + + } + + if(size < *dataLen) + { + // clean old extra info block. + memset(pData,0, *dataLen); + + // copy the new extra info block over the old + if(size > 0) + memcpy(pData, pNewHeader, size); + + // set the new extra info size + *dataLen = size; + + retVal = ZIP_OK; + } + else + retVal = ZIP_ERRNO; + + TRYFREE(pNewHeader); + + return retVal; +} diff --git a/libz/contrib/minizip/zip.h b/libz/contrib/minizip/zip.h new file mode 100644 index 000000000..8aaebb623 --- /dev/null +++ b/libz/contrib/minizip/zip.h @@ -0,0 +1,362 @@ +/* zip.h -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------- + + Changes + + See header of zip.h + +*/ + +#ifndef _zip12_H +#define _zip12_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#define HAVE_BZIP2 + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) + +#ifndef DEF_MEM_LEVEL +# if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +# else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +# endif +#endif +/* default memLevel */ + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +typedef const char* zipcharpc; + + +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. +*/ + +/* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte +*/ + +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); + +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); + +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64)); + +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + zip64 is set to 1 if a zip64 extended information block should be added to the local file header. + this MUST be '1' if the uncompressed size is >= 0xffffffff. + +*/ + + +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); + + +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64)); +/* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting)); + +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64 + )); + +/* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCrypting : crc of file to compress (needed for crypting) + */ + +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase + )); + + +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64 + )); +/* + Same than zipOpenNewFileInZip4, except + versionMadeBy : value for Version made by field + flag : value for flag field (compression level info will be added) + */ + + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); + +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32)); + +/* + Close the current file in the zipfile, for file opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + + +extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +/* + zipRemoveExtraInfoBlock - Added by Mathias Svensson + + Remove extra information block from a extra information data for the local file header or central directory header + + It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. + + 0x0001 is the signature header for the ZIP64 extra information blocks + + usage. + Remove ZIP64 Extra information from a central director extra field data + zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); + + Remove ZIP64 Extra information from a Local File Header extra field data + zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip64_H */ diff --git a/libz/contrib/pascal/example.pas b/libz/contrib/pascal/example.pas new file mode 100644 index 000000000..5518b36a7 --- /dev/null +++ b/libz/contrib/pascal/example.pas @@ -0,0 +1,599 @@ +(* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Pascal translation + * Copyright (C) 1998 by Jacques Nomssi Nzali. + * For conditions of distribution and use, see copyright notice in readme.txt + * + * Adaptation to the zlibpas interface + * Copyright (C) 2003 by Cosmin Truta. + * For conditions of distribution and use, see copyright notice in readme.txt + *) + +program example; + +{$DEFINE TEST_COMPRESS} +{DO NOT $DEFINE TEST_GZIO} +{$DEFINE TEST_DEFLATE} +{$DEFINE TEST_INFLATE} +{$DEFINE TEST_FLUSH} +{$DEFINE TEST_SYNC} +{$DEFINE TEST_DICT} + +uses SysUtils, zlibpas; + +const TESTFILE = 'foo.gz'; + +(* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + *) +const hello: PChar = 'hello, hello!'; + +const dictionary: PChar = 'hello'; + +var dictId: LongInt; (* Adler32 value of the dictionary *) + +procedure CHECK_ERR(err: Integer; msg: String); +begin + if err <> Z_OK then + begin + WriteLn(msg, ' error: ', err); + Halt(1); + end; +end; + +procedure EXIT_ERR(const msg: String); +begin + WriteLn('Error: ', msg); + Halt(1); +end; + +(* =========================================================================== + * Test compress and uncompress + *) +{$IFDEF TEST_COMPRESS} +procedure test_compress(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var err: Integer; + len: LongInt; +begin + len := StrLen(hello)+1; + + err := compress(compr, comprLen, hello, len); + CHECK_ERR(err, 'compress'); + + StrCopy(PChar(uncompr), 'garbage'); + + err := uncompress(uncompr, uncomprLen, compr, comprLen); + CHECK_ERR(err, 'uncompress'); + + if StrComp(PChar(uncompr), hello) <> 0 then + EXIT_ERR('bad uncompress') + else + WriteLn('uncompress(): ', PChar(uncompr)); +end; +{$ENDIF} + +(* =========================================================================== + * Test read/write of .gz files + *) +{$IFDEF TEST_GZIO} +procedure test_gzio(const fname: PChar; (* compressed file name *) + uncompr: Pointer; + uncomprLen: LongInt); +var err: Integer; + len: Integer; + zfile: gzFile; + pos: LongInt; +begin + len := StrLen(hello)+1; + + zfile := gzopen(fname, 'wb'); + if zfile = NIL then + begin + WriteLn('gzopen error'); + Halt(1); + end; + gzputc(zfile, 'h'); + if gzputs(zfile, 'ello') <> 4 then + begin + WriteLn('gzputs err: ', gzerror(zfile, err)); + Halt(1); + end; + {$IFDEF GZ_FORMAT_STRING} + if gzprintf(zfile, ', %s!', 'hello') <> 8 then + begin + WriteLn('gzprintf err: ', gzerror(zfile, err)); + Halt(1); + end; + {$ELSE} + if gzputs(zfile, ', hello!') <> 8 then + begin + WriteLn('gzputs err: ', gzerror(zfile, err)); + Halt(1); + end; + {$ENDIF} + gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *) + gzclose(zfile); + + zfile := gzopen(fname, 'rb'); + if zfile = NIL then + begin + WriteLn('gzopen error'); + Halt(1); + end; + + StrCopy(PChar(uncompr), 'garbage'); + + if gzread(zfile, uncompr, uncomprLen) <> len then + begin + WriteLn('gzread err: ', gzerror(zfile, err)); + Halt(1); + end; + if StrComp(PChar(uncompr), hello) <> 0 then + begin + WriteLn('bad gzread: ', PChar(uncompr)); + Halt(1); + end + else + WriteLn('gzread(): ', PChar(uncompr)); + + pos := gzseek(zfile, -8, SEEK_CUR); + if (pos <> 6) or (gztell(zfile) <> pos) then + begin + WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile)); + Halt(1); + end; + + if gzgetc(zfile) <> ' ' then + begin + WriteLn('gzgetc error'); + Halt(1); + end; + + if gzungetc(' ', zfile) <> ' ' then + begin + WriteLn('gzungetc error'); + Halt(1); + end; + + gzgets(zfile, PChar(uncompr), uncomprLen); + uncomprLen := StrLen(PChar(uncompr)); + if uncomprLen <> 7 then (* " hello!" *) + begin + WriteLn('gzgets err after gzseek: ', gzerror(zfile, err)); + Halt(1); + end; + if StrComp(PChar(uncompr), hello + 6) <> 0 then + begin + WriteLn('bad gzgets after gzseek'); + Halt(1); + end + else + WriteLn('gzgets() after gzseek: ', PChar(uncompr)); + + gzclose(zfile); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with small buffers + *) +{$IFDEF TEST_DEFLATE} +procedure test_deflate(compr: Pointer; comprLen: LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; + len: LongInt; +begin + len := StrLen(hello)+1; + + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, 'deflateInit'); + + c_stream.next_in := hello; + c_stream.next_out := compr; + + while (c_stream.total_in <> len) and + (c_stream.total_out < comprLen) do + begin + c_stream.avail_out := 1; { force small buffers } + c_stream.avail_in := 1; + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + end; + + (* Finish the stream, still forcing small buffers: *) + while TRUE do + begin + c_stream.avail_out := 1; + err := deflate(c_stream, Z_FINISH); + if err = Z_STREAM_END then + break; + CHECK_ERR(err, 'deflate'); + end; + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); +end; +{$ENDIF} + +(* =========================================================================== + * Test inflate with small buffers + *) +{$IFDEF TEST_INFLATE} +procedure test_inflate(compr: Pointer; comprLen : LongInt; + uncompr: Pointer; uncomprLen : LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := 0; + d_stream.next_out := uncompr; + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + while (d_stream.total_out < uncomprLen) and + (d_stream.total_in < comprLen) do + begin + d_stream.avail_out := 1; (* force small buffers *) + d_stream.avail_in := 1; + err := inflate(d_stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + CHECK_ERR(err, 'inflate'); + end; + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + if StrComp(PChar(uncompr), hello) <> 0 then + EXIT_ERR('bad inflate') + else + WriteLn('inflate(): ', PChar(uncompr)); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with large buffers and dynamic change of compression level + *) +{$IFDEF TEST_DEFLATE} +procedure test_large_deflate(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; +begin + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_BEST_SPEED); + CHECK_ERR(err, 'deflateInit'); + + c_stream.next_out := compr; + c_stream.avail_out := Integer(comprLen); + + (* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + *) + c_stream.next_in := uncompr; + c_stream.avail_in := Integer(uncomprLen); + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + if c_stream.avail_in <> 0 then + EXIT_ERR('deflate not greedy'); + + (* Feed in already compressed data and switch to no compression: *) + deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in := compr; + c_stream.avail_in := Integer(comprLen div 2); + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + + (* Switch back to compressing mode: *) + deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in := uncompr; + c_stream.avail_in := Integer(uncomprLen); + err := deflate(c_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'deflate'); + + err := deflate(c_stream, Z_FINISH); + if err <> Z_STREAM_END then + EXIT_ERR('deflate should report Z_STREAM_END'); + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); +end; +{$ENDIF} + +(* =========================================================================== + * Test inflate with large buffers + *) +{$IFDEF TEST_INFLATE} +procedure test_large_inflate(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := Integer(comprLen); + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + while TRUE do + begin + d_stream.next_out := uncompr; (* discard the output *) + d_stream.avail_out := Integer(uncomprLen); + err := inflate(d_stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + CHECK_ERR(err, 'large inflate'); + end; + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then + begin + WriteLn('bad large inflate: ', d_stream.total_out); + Halt(1); + end + else + WriteLn('large_inflate(): OK'); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with full flush + *) +{$IFDEF TEST_FLUSH} +procedure test_flush(compr: Pointer; var comprLen : LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; + len: Integer; +begin + len := StrLen(hello)+1; + + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, 'deflateInit'); + + c_stream.next_in := hello; + c_stream.next_out := compr; + c_stream.avail_in := 3; + c_stream.avail_out := Integer(comprLen); + err := deflate(c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, 'deflate'); + + Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *) + c_stream.avail_in := len - 3; + + err := deflate(c_stream, Z_FINISH); + if err <> Z_STREAM_END then + CHECK_ERR(err, 'deflate'); + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); + + comprLen := c_stream.total_out; +end; +{$ENDIF} + +(* =========================================================================== + * Test inflateSync() + *) +{$IFDEF TEST_SYNC} +procedure test_sync(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen : LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := 2; (* just read the zlib header *) + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + d_stream.next_out := uncompr; + d_stream.avail_out := Integer(uncomprLen); + + inflate(d_stream, Z_NO_FLUSH); + CHECK_ERR(err, 'inflate'); + + d_stream.avail_in := Integer(comprLen-2); (* read all compressed data *) + err := inflateSync(d_stream); (* but skip the damaged part *) + CHECK_ERR(err, 'inflateSync'); + + err := inflate(d_stream, Z_FINISH); + if err <> Z_DATA_ERROR then + EXIT_ERR('inflate should report DATA_ERROR'); + (* Because of incorrect adler32 *) + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + WriteLn('after inflateSync(): hel', PChar(uncompr)); +end; +{$ENDIF} + +(* =========================================================================== + * Test deflate with preset dictionary + *) +{$IFDEF TEST_DICT} +procedure test_dict_deflate(compr: Pointer; comprLen: LongInt); +var c_stream: z_stream; (* compression stream *) + err: Integer; +begin + c_stream.zalloc := NIL; + c_stream.zfree := NIL; + c_stream.opaque := NIL; + + err := deflateInit(c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, 'deflateInit'); + + err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary)); + CHECK_ERR(err, 'deflateSetDictionary'); + + dictId := c_stream.adler; + c_stream.next_out := compr; + c_stream.avail_out := Integer(comprLen); + + c_stream.next_in := hello; + c_stream.avail_in := StrLen(hello)+1; + + err := deflate(c_stream, Z_FINISH); + if err <> Z_STREAM_END then + EXIT_ERR('deflate should report Z_STREAM_END'); + + err := deflateEnd(c_stream); + CHECK_ERR(err, 'deflateEnd'); +end; +{$ENDIF} + +(* =========================================================================== + * Test inflate with a preset dictionary + *) +{$IFDEF TEST_DICT} +procedure test_dict_inflate(compr: Pointer; comprLen: LongInt; + uncompr: Pointer; uncomprLen: LongInt); +var err: Integer; + d_stream: z_stream; (* decompression stream *) +begin + StrCopy(PChar(uncompr), 'garbage'); + + d_stream.zalloc := NIL; + d_stream.zfree := NIL; + d_stream.opaque := NIL; + + d_stream.next_in := compr; + d_stream.avail_in := Integer(comprLen); + + err := inflateInit(d_stream); + CHECK_ERR(err, 'inflateInit'); + + d_stream.next_out := uncompr; + d_stream.avail_out := Integer(uncomprLen); + + while TRUE do + begin + err := inflate(d_stream, Z_NO_FLUSH); + if err = Z_STREAM_END then + break; + if err = Z_NEED_DICT then + begin + if d_stream.adler <> dictId then + EXIT_ERR('unexpected dictionary'); + err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary)); + end; + CHECK_ERR(err, 'inflate with dict'); + end; + + err := inflateEnd(d_stream); + CHECK_ERR(err, 'inflateEnd'); + + if StrComp(PChar(uncompr), hello) <> 0 then + EXIT_ERR('bad inflate with dict') + else + WriteLn('inflate with dictionary: ', PChar(uncompr)); +end; +{$ENDIF} + +var compr, uncompr: Pointer; + comprLen, uncomprLen: LongInt; + +begin + if zlibVersion^ <> ZLIB_VERSION[1] then + EXIT_ERR('Incompatible zlib version'); + + WriteLn('zlib version: ', zlibVersion); + WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags])); + + comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *) + uncomprLen := comprLen; + GetMem(compr, comprLen); + GetMem(uncompr, uncomprLen); + if (compr = NIL) or (uncompr = NIL) then + EXIT_ERR('Out of memory'); + (* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + *) + FillChar(compr^, comprLen, 0); + FillChar(uncompr^, uncomprLen, 0); + + {$IFDEF TEST_COMPRESS} + WriteLn('** Testing compress'); + test_compress(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_GZIO} + WriteLn('** Testing gzio'); + if ParamCount >= 1 then + test_gzio(ParamStr(1), uncompr, uncomprLen) + else + test_gzio(TESTFILE, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_DEFLATE} + WriteLn('** Testing deflate with small buffers'); + test_deflate(compr, comprLen); + {$ENDIF} + {$IFDEF TEST_INFLATE} + WriteLn('** Testing inflate with small buffers'); + test_inflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_DEFLATE} + WriteLn('** Testing deflate with large buffers'); + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + {$IFDEF TEST_INFLATE} + WriteLn('** Testing inflate with large buffers'); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + {$IFDEF TEST_FLUSH} + WriteLn('** Testing deflate with full flush'); + test_flush(compr, comprLen); + {$ENDIF} + {$IFDEF TEST_SYNC} + WriteLn('** Testing inflateSync'); + test_sync(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + comprLen := uncomprLen; + + {$IFDEF TEST_DICT} + WriteLn('** Testing deflate and inflate with preset dictionary'); + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + {$ENDIF} + + FreeMem(compr, comprLen); + FreeMem(uncompr, uncomprLen); +end. diff --git a/libz/contrib/pascal/readme.txt b/libz/contrib/pascal/readme.txt new file mode 100644 index 000000000..60e87c8a3 --- /dev/null +++ b/libz/contrib/pascal/readme.txt @@ -0,0 +1,76 @@ + +This directory contains a Pascal (Delphi, Kylix) interface to the +zlib data compression library. + + +Directory listing +================= + +zlibd32.mak makefile for Borland C++ +example.pas usage example of zlib +zlibpas.pas the Pascal interface to zlib +readme.txt this file + + +Compatibility notes +=================== + +- Although the name "zlib" would have been more normal for the + zlibpas unit, this name is already taken by Borland's ZLib unit. + This is somehow unfortunate, because that unit is not a genuine + interface to the full-fledged zlib functionality, but a suite of + class wrappers around zlib streams. Other essential features, + such as checksums, are missing. + It would have been more appropriate for that unit to have a name + like "ZStreams", or something similar. + +- The C and zlib-supplied types int, uInt, long, uLong, etc. are + translated directly into Pascal types of similar sizes (Integer, + LongInt, etc.), to avoid namespace pollution. In particular, + there is no conversion of unsigned int into a Pascal unsigned + integer. The Word type is non-portable and has the same size + (16 bits) both in a 16-bit and in a 32-bit environment, unlike + Integer. Even if there is a 32-bit Cardinal type, there is no + real need for unsigned int in zlib under a 32-bit environment. + +- Except for the callbacks, the zlib function interfaces are + assuming the calling convention normally used in Pascal + (__pascal for DOS and Windows16, __fastcall for Windows32). + Since the cdecl keyword is used, the old Turbo Pascal does + not work with this interface. + +- The gz* function interfaces are not translated, to avoid + interfacing problems with the C runtime library. Besides, + gzprintf(gzFile file, const char *format, ...) + cannot be translated into Pascal. + + +Legal issues +============ + +The zlibpas interface is: + Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler. + Copyright (C) 1998 by Bob Dellaca. + Copyright (C) 2003 by Cosmin Truta. + +The example program is: + Copyright (C) 1995-2003 by Jean-loup Gailly. + Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali. + Copyright (C) 2003 by Cosmin Truta. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + diff --git a/libz/contrib/pascal/zlibd32.mak b/libz/contrib/pascal/zlibd32.mak new file mode 100644 index 000000000..9bb00b7cc --- /dev/null +++ b/libz/contrib/pascal/zlibd32.mak @@ -0,0 +1,99 @@ +# Makefile for zlib +# For use with Delphi and C++ Builder under Win32 +# Updated for zlib 1.2.x by Cosmin Truta + +# ------------ Borland C++ ------------ + +# This project uses the Delphi (fastcall/register) calling convention: +LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl + +CC = bcc32 +LD = bcc32 +AR = tlib +# do not use "-pr" in CFLAGS +CFLAGS = -a -d -k- -O2 $(LOC) +LDFLAGS = + + +# variables +ZLIB_LIB = zlib.lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# For the sake of the old Borland make, +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + + +# cleanup +clean: + -del *.obj + -del *.exe + -del *.lib + -del *.tds + -del zlib.bak + -del foo.gz + diff --git a/libz/contrib/pascal/zlibpas.pas b/libz/contrib/pascal/zlibpas.pas new file mode 100644 index 000000000..e6a0782b4 --- /dev/null +++ b/libz/contrib/pascal/zlibpas.pas @@ -0,0 +1,276 @@ +(* zlibpas -- Pascal interface to the zlib data compression library + * + * Copyright (C) 2003 Cosmin Truta. + * Derived from original sources by Bob Dellaca. + * For conditions of distribution and use, see copyright notice in readme.txt + *) + +unit zlibpas; + +interface + +const + ZLIB_VERSION = '1.2.8'; + ZLIB_VERNUM = $1280; + +type + alloc_func = function(opaque: Pointer; items, size: Integer): Pointer; + cdecl; + free_func = procedure(opaque, address: Pointer); + cdecl; + + in_func = function(opaque: Pointer; var buf: PByte): Integer; + cdecl; + out_func = function(opaque: Pointer; buf: PByte; size: Integer): Integer; + cdecl; + + z_streamp = ^z_stream; + z_stream = packed record + next_in: PChar; (* next input byte *) + avail_in: Integer; (* number of bytes available at next_in *) + total_in: LongInt; (* total nb of input bytes read so far *) + + next_out: PChar; (* next output byte should be put there *) + avail_out: Integer; (* remaining free space at next_out *) + total_out: LongInt; (* total nb of bytes output so far *) + + msg: PChar; (* last error message, NULL if no error *) + state: Pointer; (* not visible by applications *) + + zalloc: alloc_func; (* used to allocate the internal state *) + zfree: free_func; (* used to free the internal state *) + opaque: Pointer; (* private data object passed to zalloc and zfree *) + + data_type: Integer; (* best guess about the data type: ascii or binary *) + adler: LongInt; (* adler32 value of the uncompressed data *) + reserved: LongInt; (* reserved for future use *) + end; + + gz_headerp = ^gz_header; + gz_header = packed record + text: Integer; (* true if compressed data believed to be text *) + time: LongInt; (* modification time *) + xflags: Integer; (* extra flags (not used when writing a gzip file) *) + os: Integer; (* operating system *) + extra: PChar; (* pointer to extra field or Z_NULL if none *) + extra_len: Integer; (* extra field length (valid if extra != Z_NULL) *) + extra_max: Integer; (* space at extra (only when reading header) *) + name: PChar; (* pointer to zero-terminated file name or Z_NULL *) + name_max: Integer; (* space at name (only when reading header) *) + comment: PChar; (* pointer to zero-terminated comment or Z_NULL *) + comm_max: Integer; (* space at comment (only when reading header) *) + hcrc: Integer; (* true if there was or will be a header crc *) + done: Integer; (* true when done reading gzip header *) + end; + +(* constants *) +const + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + Z_BLOCK = 5; + Z_TREES = 6; + + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = -1; + Z_STREAM_ERROR = -2; + Z_DATA_ERROR = -3; + Z_MEM_ERROR = -4; + Z_BUF_ERROR = -5; + Z_VERSION_ERROR = -6; + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = -1; + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_RLE = 3; + Z_FIXED = 4; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_TEXT = 1; + Z_ASCII = 1; + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + +(* basic functions *) +function zlibVersion: PChar; +function deflateInit(var strm: z_stream; level: Integer): Integer; +function deflate(var strm: z_stream; flush: Integer): Integer; +function deflateEnd(var strm: z_stream): Integer; +function inflateInit(var strm: z_stream): Integer; +function inflate(var strm: z_stream; flush: Integer): Integer; +function inflateEnd(var strm: z_stream): Integer; + +(* advanced functions *) +function deflateInit2(var strm: z_stream; level, method, windowBits, + memLevel, strategy: Integer): Integer; +function deflateSetDictionary(var strm: z_stream; const dictionary: PChar; + dictLength: Integer): Integer; +function deflateCopy(var dest, source: z_stream): Integer; +function deflateReset(var strm: z_stream): Integer; +function deflateParams(var strm: z_stream; level, strategy: Integer): Integer; +function deflateTune(var strm: z_stream; good_length, max_lazy, nice_length, max_chain: Integer): Integer; +function deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt; +function deflatePending(var strm: z_stream; var pending: Integer; var bits: Integer): Integer; +function deflatePrime(var strm: z_stream; bits, value: Integer): Integer; +function deflateSetHeader(var strm: z_stream; head: gz_header): Integer; +function inflateInit2(var strm: z_stream; windowBits: Integer): Integer; +function inflateSetDictionary(var strm: z_stream; const dictionary: PChar; + dictLength: Integer): Integer; +function inflateSync(var strm: z_stream): Integer; +function inflateCopy(var dest, source: z_stream): Integer; +function inflateReset(var strm: z_stream): Integer; +function inflateReset2(var strm: z_stream; windowBits: Integer): Integer; +function inflatePrime(var strm: z_stream; bits, value: Integer): Integer; +function inflateMark(var strm: z_stream): LongInt; +function inflateGetHeader(var strm: z_stream; var head: gz_header): Integer; +function inflateBackInit(var strm: z_stream; + windowBits: Integer; window: PChar): Integer; +function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer; + out_fn: out_func; out_desc: Pointer): Integer; +function inflateBackEnd(var strm: z_stream): Integer; +function zlibCompileFlags: LongInt; + +(* utility functions *) +function compress(dest: PChar; var destLen: LongInt; + const source: PChar; sourceLen: LongInt): Integer; +function compress2(dest: PChar; var destLen: LongInt; + const source: PChar; sourceLen: LongInt; + level: Integer): Integer; +function compressBound(sourceLen: LongInt): LongInt; +function uncompress(dest: PChar; var destLen: LongInt; + const source: PChar; sourceLen: LongInt): Integer; + +(* checksum functions *) +function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt; +function adler32_combine(adler1, adler2, len2: LongInt): LongInt; +function crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt; +function crc32_combine(crc1, crc2, len2: LongInt): LongInt; + +(* various hacks, don't look :) *) +function deflateInit_(var strm: z_stream; level: Integer; + const version: PChar; stream_size: Integer): Integer; +function inflateInit_(var strm: z_stream; const version: PChar; + stream_size: Integer): Integer; +function deflateInit2_(var strm: z_stream; + level, method, windowBits, memLevel, strategy: Integer; + const version: PChar; stream_size: Integer): Integer; +function inflateInit2_(var strm: z_stream; windowBits: Integer; + const version: PChar; stream_size: Integer): Integer; +function inflateBackInit_(var strm: z_stream; + windowBits: Integer; window: PChar; + const version: PChar; stream_size: Integer): Integer; + + +implementation + +{$L adler32.obj} +{$L compress.obj} +{$L crc32.obj} +{$L deflate.obj} +{$L infback.obj} +{$L inffast.obj} +{$L inflate.obj} +{$L inftrees.obj} +{$L trees.obj} +{$L uncompr.obj} +{$L zutil.obj} + +function adler32; external; +function adler32_combine; external; +function compress; external; +function compress2; external; +function compressBound; external; +function crc32; external; +function crc32_combine; external; +function deflate; external; +function deflateBound; external; +function deflateCopy; external; +function deflateEnd; external; +function deflateInit_; external; +function deflateInit2_; external; +function deflateParams; external; +function deflatePending; external; +function deflatePrime; external; +function deflateReset; external; +function deflateSetDictionary; external; +function deflateSetHeader; external; +function deflateTune; external; +function inflate; external; +function inflateBack; external; +function inflateBackEnd; external; +function inflateBackInit_; external; +function inflateCopy; external; +function inflateEnd; external; +function inflateGetHeader; external; +function inflateInit_; external; +function inflateInit2_; external; +function inflateMark; external; +function inflatePrime; external; +function inflateReset; external; +function inflateReset2; external; +function inflateSetDictionary; external; +function inflateSync; external; +function uncompress; external; +function zlibCompileFlags; external; +function zlibVersion; external; + +function deflateInit(var strm: z_stream; level: Integer): Integer; +begin + Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream)); +end; + +function deflateInit2(var strm: z_stream; level, method, windowBits, memLevel, + strategy: Integer): Integer; +begin + Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit(var strm: z_stream): Integer; +begin + Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateInit2(var strm: z_stream; windowBits: Integer): Integer; +begin + Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(z_stream)); +end; + +function inflateBackInit(var strm: z_stream; + windowBits: Integer; window: PChar): Integer; +begin + Result := inflateBackInit_(strm, windowBits, window, + ZLIB_VERSION, sizeof(z_stream)); +end; + +function _malloc(Size: Integer): Pointer; cdecl; +begin + GetMem(Result, Size); +end; + +procedure _free(Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; +begin + FillChar(P^, count, B); +end; + +procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; +begin + Move(source^, dest^, count); +end; + +end. diff --git a/libz/contrib/puff/README b/libz/contrib/puff/README new file mode 100644 index 000000000..bbc4cb595 --- /dev/null +++ b/libz/contrib/puff/README @@ -0,0 +1,63 @@ +Puff -- A Simple Inflate +3 Mar 2003 +Mark Adler +madler@alumni.caltech.edu + +What this is -- + +puff.c provides the routine puff() to decompress the deflate data format. It +does so more slowly than zlib, but the code is about one-fifth the size of the +inflate code in zlib, and written to be very easy to read. + +Why I wrote this -- + +puff.c was written to document the deflate format unambiguously, by virtue of +being working C code. It is meant to supplement RFC 1951, which formally +describes the deflate format. I have received many questions on details of the +deflate format, and I hope that reading this code will answer those questions. +puff.c is heavily commented with details of the deflate format, especially +those little nooks and cranies of the format that might not be obvious from a +specification. + +puff.c may also be useful in applications where code size or memory usage is a +very limited resource, and speed is not as important. + +How to use it -- + +Well, most likely you should just be reading puff.c and using zlib for actual +applications, but if you must ... + +Include puff.h in your code, which provides this prototype: + +int puff(unsigned char *dest, /* pointer to destination pointer */ + unsigned long *destlen, /* amount of output space */ + unsigned char *source, /* pointer to source data pointer */ + unsigned long *sourcelen); /* amount of input available */ + +Then you can call puff() to decompress a deflate stream that is in memory in +its entirety at source, to a sufficiently sized block of memory for the +decompressed data at dest. puff() is the only external symbol in puff.c The +only C library functions that puff.c needs are setjmp() and longjmp(), which +are used to simplify error checking in the code to improve readabilty. puff.c +does no memory allocation, and uses less than 2K bytes off of the stack. + +If destlen is not enough space for the uncompressed data, then inflate will +return an error without writing more than destlen bytes. Note that this means +that in order to decompress the deflate data successfully, you need to know +the size of the uncompressed data ahead of time. + +If needed, puff() can determine the size of the uncompressed data with no +output space. This is done by passing dest equal to (unsigned char *)0. Then +the initial value of *destlen is ignored and *destlen is set to the length of +the uncompressed data. So if the size of the uncompressed data is not known, +then two passes of puff() can be used--first to determine the size, and second +to do the actual inflation after allocating the appropriate memory. Not +pretty, but it works. (This is one of the reasons you should be using zlib.) + +The deflate format is self-terminating. If the deflate stream does not end +in *sourcelen bytes, puff() will return an error without reading at or past +endsource. + +On return, *sourcelen is updated to the amount of input data consumed, and +*destlen is updated to the size of the uncompressed data. See the comments +in puff.c for the possible return codes for puff(). diff --git a/libz/contrib/puff/puff.c b/libz/contrib/puff/puff.c new file mode 100644 index 000000000..ba58483d5 --- /dev/null +++ b/libz/contrib/puff/puff.c @@ -0,0 +1,840 @@ +/* + * puff.c + * Copyright (C) 2002-2013 Mark Adler + * For conditions of distribution and use, see copyright notice in puff.h + * version 2.3, 21 Jan 2013 + * + * puff.c is a simple inflate written to be an unambiguous way to specify the + * deflate format. It is not written for speed but rather simplicity. As a + * side benefit, this code might actually be useful when small code is more + * important than speed, such as bootstrap applications. For typical deflate + * data, zlib's inflate() is about four times as fast as puff(). zlib's + * inflate compiles to around 20K on my machine, whereas puff.c compiles to + * around 4K on my machine (a PowerPC using GNU cc). If the faster decode() + * function here is used, then puff() is only twice as slow as zlib's + * inflate(). + * + * All dynamically allocated memory comes from the stack. The stack required + * is less than 2K bytes. This code is compatible with 16-bit int's and + * assumes that long's are at least 32 bits. puff.c uses the short data type, + * assumed to be 16 bits, for arrays in order to to conserve memory. The code + * works whether integers are stored big endian or little endian. + * + * In the comments below are "Format notes" that describe the inflate process + * and document some of the less obvious aspects of the format. This source + * code is meant to supplement RFC 1951, which formally describes the deflate + * format: + * + * http://www.zlib.org/rfc-deflate.html + */ + +/* + * Change history: + * + * 1.0 10 Feb 2002 - First version + * 1.1 17 Feb 2002 - Clarifications of some comments and notes + * - Update puff() dest and source pointers on negative + * errors to facilitate debugging deflators + * - Remove longest from struct huffman -- not needed + * - Simplify offs[] index in construct() + * - Add input size and checking, using longjmp() to + * maintain easy readability + * - Use short data type for large arrays + * - Use pointers instead of long to specify source and + * destination sizes to avoid arbitrary 4 GB limits + * 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!), + * but leave simple version for readabilty + * - Make sure invalid distances detected if pointers + * are 16 bits + * - Fix fixed codes table error + * - Provide a scanning mode for determining size of + * uncompressed data + * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly] + * - Add a puff.h file for the interface + * - Add braces in puff() for else do [Gailly] + * - Use indexes instead of pointers for readability + * 1.4 31 Mar 2002 - Simplify construct() code set check + * - Fix some comments + * - Add FIXLCODES #define + * 1.5 6 Apr 2002 - Minor comment fixes + * 1.6 7 Aug 2002 - Minor format changes + * 1.7 3 Mar 2003 - Added test code for distribution + * - Added zlib-like license + * 1.8 9 Jan 2004 - Added some comments on no distance codes case + * 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland] + * - Catch missing end-of-block symbol error + * 2.0 25 Jul 2008 - Add #define to permit distance too far back + * - Add option in TEST code for puff to write the data + * - Add option in TEST code to skip input bytes + * - Allow TEST code to read from piped stdin + * 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers + * - Avoid unsigned comparisons for even happier compilers + * 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer] + * - Add const where appropriate [Oberhumer] + * - Split if's and ?'s for coverage testing + * - Break out test code to separate file + * - Move NIL to puff.h + * - Allow incomplete code only if single code length is 1 + * - Add full code coverage test to Makefile + * 2.3 21 Jan 2013 - Check for invalid code length codes in dynamic blocks + */ + +#include /* for setjmp(), longjmp(), and jmp_buf */ +#include "puff.h" /* prototype for puff() */ + +#define local static /* for local function definitions */ + +/* + * Maximums for allocations and loops. It is not useful to change these -- + * they are fixed by the deflate format. + */ +#define MAXBITS 15 /* maximum bits in a code */ +#define MAXLCODES 286 /* maximum number of literal/length codes */ +#define MAXDCODES 30 /* maximum number of distance codes */ +#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */ +#define FIXLCODES 288 /* number of fixed literal/length codes */ + +/* input and output state */ +struct state { + /* output state */ + unsigned char *out; /* output buffer */ + unsigned long outlen; /* available space at out */ + unsigned long outcnt; /* bytes written to out so far */ + + /* input state */ + const unsigned char *in; /* input buffer */ + unsigned long inlen; /* available input at in */ + unsigned long incnt; /* bytes read so far */ + int bitbuf; /* bit buffer */ + int bitcnt; /* number of bits in bit buffer */ + + /* input limit error return state for bits() and decode() */ + jmp_buf env; +}; + +/* + * Return need bits from the input stream. This always leaves less than + * eight bits in the buffer. bits() works properly for need == 0. + * + * Format notes: + * + * - Bits are stored in bytes from the least significant bit to the most + * significant bit. Therefore bits are dropped from the bottom of the bit + * buffer, using shift right, and new bytes are appended to the top of the + * bit buffer, using shift left. + */ +local int bits(struct state *s, int need) +{ + long val; /* bit accumulator (can use up to 20 bits) */ + + /* load at least need bits into val */ + val = s->bitbuf; + while (s->bitcnt < need) { + if (s->incnt == s->inlen) + longjmp(s->env, 1); /* out of input */ + val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */ + s->bitcnt += 8; + } + + /* drop need bits and update buffer, always zero to seven bits left */ + s->bitbuf = (int)(val >> need); + s->bitcnt -= need; + + /* return need bits, zeroing the bits above that */ + return (int)(val & ((1L << need) - 1)); +} + +/* + * Process a stored block. + * + * Format notes: + * + * - After the two-bit stored block type (00), the stored block length and + * stored bytes are byte-aligned for fast copying. Therefore any leftover + * bits in the byte that has the last bit of the type, as many as seven, are + * discarded. The value of the discarded bits are not defined and should not + * be checked against any expectation. + * + * - The second inverted copy of the stored block length does not have to be + * checked, but it's probably a good idea to do so anyway. + * + * - A stored block can have zero length. This is sometimes used to byte-align + * subsets of the compressed data for random access or partial recovery. + */ +local int stored(struct state *s) +{ + unsigned len; /* length of stored block */ + + /* discard leftover bits from current byte (assumes s->bitcnt < 8) */ + s->bitbuf = 0; + s->bitcnt = 0; + + /* get length and check against its one's complement */ + if (s->incnt + 4 > s->inlen) + return 2; /* not enough input */ + len = s->in[s->incnt++]; + len |= s->in[s->incnt++] << 8; + if (s->in[s->incnt++] != (~len & 0xff) || + s->in[s->incnt++] != ((~len >> 8) & 0xff)) + return -2; /* didn't match complement! */ + + /* copy len bytes from in to out */ + if (s->incnt + len > s->inlen) + return 2; /* not enough input */ + if (s->out != NIL) { + if (s->outcnt + len > s->outlen) + return 1; /* not enough output space */ + while (len--) + s->out[s->outcnt++] = s->in[s->incnt++]; + } + else { /* just scanning */ + s->outcnt += len; + s->incnt += len; + } + + /* done with a valid stored block */ + return 0; +} + +/* + * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of + * each length, which for a canonical code are stepped through in order. + * symbol[] are the symbol values in canonical order, where the number of + * entries is the sum of the counts in count[]. The decoding process can be + * seen in the function decode() below. + */ +struct huffman { + short *count; /* number of symbols of each length */ + short *symbol; /* canonically ordered symbols */ +}; + +/* + * Decode a code from the stream s using huffman table h. Return the symbol or + * a negative value if there is an error. If all of the lengths are zero, i.e. + * an empty code, or if the code is incomplete and an invalid code is received, + * then -10 is returned after reading MAXBITS bits. + * + * Format notes: + * + * - The codes as stored in the compressed data are bit-reversed relative to + * a simple integer ordering of codes of the same lengths. Hence below the + * bits are pulled from the compressed data one at a time and used to + * build the code value reversed from what is in the stream in order to + * permit simple integer comparisons for decoding. A table-based decoding + * scheme (as used in zlib) does not need to do this reversal. + * + * - The first code for the shortest length is all zeros. Subsequent codes of + * the same length are simply integer increments of the previous code. When + * moving up a length, a zero bit is appended to the code. For a complete + * code, the last code of the longest length will be all ones. + * + * - Incomplete codes are handled by this decoder, since they are permitted + * in the deflate format. See the format notes for fixed() and dynamic(). + */ +#ifdef SLOW +local int decode(struct state *s, const struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + + code = first = index = 0; + for (len = 1; len <= MAXBITS; len++) { + code |= bits(s, 1); /* get next bit */ + count = h->count[len]; + if (code - count < first) /* if length len, return symbol */ + return h->symbol[index + (code - first)]; + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + } + return -10; /* ran out of codes */ +} + +/* + * A faster version of decode() for real applications of this code. It's not + * as readable, but it makes puff() twice as fast. And it only makes the code + * a few percent larger. + */ +#else /* !SLOW */ +local int decode(struct state *s, const struct huffman *h) +{ + int len; /* current number of bits in code */ + int code; /* len bits being decoded */ + int first; /* first code of length len */ + int count; /* number of codes of length len */ + int index; /* index of first code of length len in symbol table */ + int bitbuf; /* bits from stream */ + int left; /* bits left in next or left to process */ + short *next; /* next number of codes */ + + bitbuf = s->bitbuf; + left = s->bitcnt; + code = first = index = 0; + len = 1; + next = h->count + 1; + while (1) { + while (left--) { + code |= bitbuf & 1; + bitbuf >>= 1; + count = *next++; + if (code - count < first) { /* if length len, return symbol */ + s->bitbuf = bitbuf; + s->bitcnt = (s->bitcnt - len) & 7; + return h->symbol[index + (code - first)]; + } + index += count; /* else update for next length */ + first += count; + first <<= 1; + code <<= 1; + len++; + } + left = (MAXBITS+1) - len; + if (left == 0) + break; + if (s->incnt == s->inlen) + longjmp(s->env, 1); /* out of input */ + bitbuf = s->in[s->incnt++]; + if (left > 8) + left = 8; + } + return -10; /* ran out of codes */ +} +#endif /* SLOW */ + +/* + * Given the list of code lengths length[0..n-1] representing a canonical + * Huffman code for n symbols, construct the tables required to decode those + * codes. Those tables are the number of codes of each length, and the symbols + * sorted by length, retaining their original order within each length. The + * return value is zero for a complete code set, negative for an over- + * subscribed code set, and positive for an incomplete code set. The tables + * can be used if the return value is zero or positive, but they cannot be used + * if the return value is negative. If the return value is zero, it is not + * possible for decode() using that table to return an error--any stream of + * enough bits will resolve to a symbol. If the return value is positive, then + * it is possible for decode() using that table to return an error for received + * codes past the end of the incomplete lengths. + * + * Not used by decode(), but used for error checking, h->count[0] is the number + * of the n symbols not in the code. So n - h->count[0] is the number of + * codes. This is useful for checking for incomplete codes that have more than + * one symbol, which is an error in a dynamic block. + * + * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS + * This is assured by the construction of the length arrays in dynamic() and + * fixed() and is not verified by construct(). + * + * Format notes: + * + * - Permitted and expected examples of incomplete codes are one of the fixed + * codes and any code with a single symbol which in deflate is coded as one + * bit instead of zero bits. See the format notes for fixed() and dynamic(). + * + * - Within a given code length, the symbols are kept in ascending order for + * the code bits definition. + */ +local int construct(struct huffman *h, const short *length, int n) +{ + int symbol; /* current symbol when stepping through length[] */ + int len; /* current length when stepping through h->count[] */ + int left; /* number of possible codes left of current length */ + short offs[MAXBITS+1]; /* offsets in symbol table for each length */ + + /* count number of codes of each length */ + for (len = 0; len <= MAXBITS; len++) + h->count[len] = 0; + for (symbol = 0; symbol < n; symbol++) + (h->count[length[symbol]])++; /* assumes lengths are within bounds */ + if (h->count[0] == n) /* no codes! */ + return 0; /* complete, but decode() will fail */ + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; /* one possible code of zero length */ + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; /* one more bit, double codes left */ + left -= h->count[len]; /* deduct count from possible codes */ + if (left < 0) + return left; /* over-subscribed--return negative */ + } /* left > 0 means incomplete */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + h->count[len]; + + /* + * put symbols in table sorted by length, by symbol order within each + * length + */ + for (symbol = 0; symbol < n; symbol++) + if (length[symbol] != 0) + h->symbol[offs[length[symbol]]++] = symbol; + + /* return zero for complete set, positive for incomplete set */ + return left; +} + +/* + * Decode literal/length and distance codes until an end-of-block code. + * + * Format notes: + * + * - Compressed data that is after the block type if fixed or after the code + * description if dynamic is a combination of literals and length/distance + * pairs terminated by and end-of-block code. Literals are simply Huffman + * coded bytes. A length/distance pair is a coded length followed by a + * coded distance to represent a string that occurs earlier in the + * uncompressed data that occurs again at the current location. + * + * - Literals, lengths, and the end-of-block code are combined into a single + * code of up to 286 symbols. They are 256 literals (0..255), 29 length + * symbols (257..285), and the end-of-block symbol (256). + * + * - There are 256 possible lengths (3..258), and so 29 symbols are not enough + * to represent all of those. Lengths 3..10 and 258 are in fact represented + * by just a length symbol. Lengths 11..257 are represented as a symbol and + * some number of extra bits that are added as an integer to the base length + * of the length symbol. The number of extra bits is determined by the base + * length symbol. These are in the static arrays below, lens[] for the base + * lengths and lext[] for the corresponding number of extra bits. + * + * - The reason that 258 gets its own symbol is that the longest length is used + * often in highly redundant files. Note that 258 can also be coded as the + * base value 227 plus the maximum extra value of 31. While a good deflate + * should never do this, it is not an error, and should be decoded properly. + * + * - If a length is decoded, including its extra bits if any, then it is + * followed a distance code. There are up to 30 distance symbols. Again + * there are many more possible distances (1..32768), so extra bits are added + * to a base value represented by the symbol. The distances 1..4 get their + * own symbol, but the rest require extra bits. The base distances and + * corresponding number of extra bits are below in the static arrays dist[] + * and dext[]. + * + * - Literal bytes are simply written to the output. A length/distance pair is + * an instruction to copy previously uncompressed bytes to the output. The + * copy is from distance bytes back in the output stream, copying for length + * bytes. + * + * - Distances pointing before the beginning of the output data are not + * permitted. + * + * - Overlapped copies, where the length is greater than the distance, are + * allowed and common. For example, a distance of one and a length of 258 + * simply copies the last byte 258 times. A distance of four and a length of + * twelve copies the last four bytes three times. A simple forward copy + * ignoring whether the length is greater than the distance or not implements + * this correctly. You should not use memcpy() since its behavior is not + * defined for overlapped arrays. You should not use memmove() or bcopy() + * since though their behavior -is- defined for overlapping arrays, it is + * defined to do the wrong thing in this case. + */ +local int codes(struct state *s, + const struct huffman *lencode, + const struct huffman *distcode) +{ + int symbol; /* decoded symbol */ + int len; /* length for copy */ + unsigned dist; /* distance for copy */ + static const short lens[29] = { /* Size base for length codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; + static const short lext[29] = { /* Extra bits for length codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; + static const short dists[30] = { /* Offset base for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; + static const short dext[30] = { /* Extra bits for distance codes 0..29 */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + /* decode literals and length/distance pairs */ + do { + symbol = decode(s, lencode); + if (symbol < 0) + return symbol; /* invalid symbol */ + if (symbol < 256) { /* literal: symbol is the byte */ + /* write out the literal */ + if (s->out != NIL) { + if (s->outcnt == s->outlen) + return 1; + s->out[s->outcnt] = symbol; + } + s->outcnt++; + } + else if (symbol > 256) { /* length */ + /* get and compute length */ + symbol -= 257; + if (symbol >= 29) + return -10; /* invalid fixed code */ + len = lens[symbol] + bits(s, lext[symbol]); + + /* get and check distance */ + symbol = decode(s, distcode); + if (symbol < 0) + return symbol; /* invalid symbol */ + dist = dists[symbol] + bits(s, dext[symbol]); +#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (dist > s->outcnt) + return -11; /* distance too far back */ +#endif + + /* copy length bytes from distance bytes back */ + if (s->out != NIL) { + if (s->outcnt + len > s->outlen) + return 1; + while (len--) { + s->out[s->outcnt] = +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + dist > s->outcnt ? + 0 : +#endif + s->out[s->outcnt - dist]; + s->outcnt++; + } + } + else + s->outcnt += len; + } + } while (symbol != 256); /* end of block symbol */ + + /* done with a valid fixed or dynamic block */ + return 0; +} + +/* + * Process a fixed codes block. + * + * Format notes: + * + * - This block type can be useful for compressing small amounts of data for + * which the size of the code descriptions in a dynamic block exceeds the + * benefit of custom codes for that block. For fixed codes, no bits are + * spent on code descriptions. Instead the code lengths for literal/length + * codes and distance codes are fixed. The specific lengths for each symbol + * can be seen in the "for" loops below. + * + * - The literal/length code is complete, but has two symbols that are invalid + * and should result in an error if received. This cannot be implemented + * simply as an incomplete code since those two symbols are in the "middle" + * of the code. They are eight bits long and the longest literal/length\ + * code is nine bits. Therefore the code must be constructed with those + * symbols, and the invalid symbols must be detected after decoding. + * + * - The fixed distance codes also have two invalid symbols that should result + * in an error if received. Since all of the distance codes are the same + * length, this can be implemented as an incomplete code. Then the invalid + * codes are detected while decoding. + */ +local int fixed(struct state *s) +{ + static int virgin = 1; + static short lencnt[MAXBITS+1], lensym[FIXLCODES]; + static short distcnt[MAXBITS+1], distsym[MAXDCODES]; + static struct huffman lencode, distcode; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + int symbol; + short lengths[FIXLCODES]; + + /* construct lencode and distcode */ + lencode.count = lencnt; + lencode.symbol = lensym; + distcode.count = distcnt; + distcode.symbol = distsym; + + /* literal/length table */ + for (symbol = 0; symbol < 144; symbol++) + lengths[symbol] = 8; + for (; symbol < 256; symbol++) + lengths[symbol] = 9; + for (; symbol < 280; symbol++) + lengths[symbol] = 7; + for (; symbol < FIXLCODES; symbol++) + lengths[symbol] = 8; + construct(&lencode, lengths, FIXLCODES); + + /* distance table */ + for (symbol = 0; symbol < MAXDCODES; symbol++) + lengths[symbol] = 5; + construct(&distcode, lengths, MAXDCODES); + + /* do this just once */ + virgin = 0; + } + + /* decode data until end-of-block code */ + return codes(s, &lencode, &distcode); +} + +/* + * Process a dynamic codes block. + * + * Format notes: + * + * - A dynamic block starts with a description of the literal/length and + * distance codes for that block. New dynamic blocks allow the compressor to + * rapidly adapt to changing data with new codes optimized for that data. + * + * - The codes used by the deflate format are "canonical", which means that + * the actual bits of the codes are generated in an unambiguous way simply + * from the number of bits in each code. Therefore the code descriptions + * are simply a list of code lengths for each symbol. + * + * - The code lengths are stored in order for the symbols, so lengths are + * provided for each of the literal/length symbols, and for each of the + * distance symbols. + * + * - If a symbol is not used in the block, this is represented by a zero as + * as the code length. This does not mean a zero-length code, but rather + * that no code should be created for this symbol. There is no way in the + * deflate format to represent a zero-length code. + * + * - The maximum number of bits in a code is 15, so the possible lengths for + * any code are 1..15. + * + * - The fact that a length of zero is not permitted for a code has an + * interesting consequence. Normally if only one symbol is used for a given + * code, then in fact that code could be represented with zero bits. However + * in deflate, that code has to be at least one bit. So for example, if + * only a single distance base symbol appears in a block, then it will be + * represented by a single code of length one, in particular one 0 bit. This + * is an incomplete code, since if a 1 bit is received, it has no meaning, + * and should result in an error. So incomplete distance codes of one symbol + * should be permitted, and the receipt of invalid codes should be handled. + * + * - It is also possible to have a single literal/length code, but that code + * must be the end-of-block code, since every dynamic block has one. This + * is not the most efficient way to create an empty block (an empty fixed + * block is fewer bits), but it is allowed by the format. So incomplete + * literal/length codes of one symbol should also be permitted. + * + * - If there are only literal codes and no lengths, then there are no distance + * codes. This is represented by one distance code with zero bits. + * + * - The list of up to 286 length/literal lengths and up to 30 distance lengths + * are themselves compressed using Huffman codes and run-length encoding. In + * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means + * that length, and the symbols 16, 17, and 18 are run-length instructions. + * Each of 16, 17, and 18 are follwed by extra bits to define the length of + * the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10 + * zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols + * are common, hence the special coding for zero lengths. + * + * - The symbols for 0..18 are Huffman coded, and so that code must be + * described first. This is simply a sequence of up to 19 three-bit values + * representing no code (0) or the code length for that symbol (1..7). + * + * - A dynamic block starts with three fixed-size counts from which is computed + * the number of literal/length code lengths, the number of distance code + * lengths, and the number of code length code lengths (ok, you come up with + * a better name!) in the code descriptions. For the literal/length and + * distance codes, lengths after those provided are considered zero, i.e. no + * code. The code length code lengths are received in a permuted order (see + * the order[] array below) to make a short code length code length list more + * likely. As it turns out, very short and very long codes are less likely + * to be seen in a dynamic code description, hence what may appear initially + * to be a peculiar ordering. + * + * - Given the number of literal/length code lengths (nlen) and distance code + * lengths (ndist), then they are treated as one long list of nlen + ndist + * code lengths. Therefore run-length coding can and often does cross the + * boundary between the two sets of lengths. + * + * - So to summarize, the code description at the start of a dynamic block is + * three counts for the number of code lengths for the literal/length codes, + * the distance codes, and the code length codes. This is followed by the + * code length code lengths, three bits each. This is used to construct the + * code length code which is used to read the remainder of the lengths. Then + * the literal/length code lengths and distance lengths are read as a single + * set of lengths using the code length codes. Codes are constructed from + * the resulting two sets of lengths, and then finally you can start + * decoding actual compressed data in the block. + * + * - For reference, a "typical" size for the code description in a dynamic + * block is around 80 bytes. + */ +local int dynamic(struct state *s) +{ + int nlen, ndist, ncode; /* number of lengths in descriptor */ + int index; /* index of lengths[] */ + int err; /* construct() return value */ + short lengths[MAXCODES]; /* descriptor code lengths */ + short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */ + short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */ + struct huffman lencode, distcode; /* length and distance codes */ + static const short order[19] = /* permutation of code length codes */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* construct lencode and distcode */ + lencode.count = lencnt; + lencode.symbol = lensym; + distcode.count = distcnt; + distcode.symbol = distsym; + + /* get number of lengths in each table, check lengths */ + nlen = bits(s, 5) + 257; + ndist = bits(s, 5) + 1; + ncode = bits(s, 4) + 4; + if (nlen > MAXLCODES || ndist > MAXDCODES) + return -3; /* bad counts */ + + /* read code length code lengths (really), missing lengths are zero */ + for (index = 0; index < ncode; index++) + lengths[order[index]] = bits(s, 3); + for (; index < 19; index++) + lengths[order[index]] = 0; + + /* build huffman table for code lengths codes (use lencode temporarily) */ + err = construct(&lencode, lengths, 19); + if (err != 0) /* require complete code set here */ + return -4; + + /* read length/literal and distance code length tables */ + index = 0; + while (index < nlen + ndist) { + int symbol; /* decoded value */ + int len; /* last length to repeat */ + + symbol = decode(s, &lencode); + if (symbol < 0) + return symbol; /* invalid symbol */ + if (symbol < 16) /* length in 0..15 */ + lengths[index++] = symbol; + else { /* repeat instruction */ + len = 0; /* assume repeating zeros */ + if (symbol == 16) { /* repeat last length 3..6 times */ + if (index == 0) + return -5; /* no last length! */ + len = lengths[index - 1]; /* last length */ + symbol = 3 + bits(s, 2); + } + else if (symbol == 17) /* repeat zero 3..10 times */ + symbol = 3 + bits(s, 3); + else /* == 18, repeat zero 11..138 times */ + symbol = 11 + bits(s, 7); + if (index + symbol > nlen + ndist) + return -6; /* too many lengths! */ + while (symbol--) /* repeat last or zero symbol times */ + lengths[index++] = len; + } + } + + /* check for end-of-block code -- there better be one! */ + if (lengths[256] == 0) + return -9; + + /* build huffman table for literal/length codes */ + err = construct(&lencode, lengths, nlen); + if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1])) + return -7; /* incomplete code ok only for single length 1 code */ + + /* build huffman table for distance codes */ + err = construct(&distcode, lengths + nlen, ndist); + if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1])) + return -8; /* incomplete code ok only for single length 1 code */ + + /* decode data until end-of-block code */ + return codes(s, &lencode, &distcode); +} + +/* + * Inflate source to dest. On return, destlen and sourcelen are updated to the + * size of the uncompressed data and the size of the deflate data respectively. + * On success, the return value of puff() is zero. If there is an error in the + * source data, i.e. it is not in the deflate format, then a negative value is + * returned. If there is not enough input available or there is not enough + * output space, then a positive error is returned. In that case, destlen and + * sourcelen are not updated to facilitate retrying from the beginning with the + * provision of more input data or more output space. In the case of invalid + * inflate data (a negative error), the dest and source pointers are updated to + * facilitate the debugging of deflators. + * + * puff() also has a mode to determine the size of the uncompressed output with + * no output written. For this dest must be (unsigned char *)0. In this case, + * the input value of *destlen is ignored, and on return *destlen is set to the + * size of the uncompressed output. + * + * The return codes are: + * + * 2: available inflate data did not terminate + * 1: output space exhausted before completing inflate + * 0: successful inflate + * -1: invalid block type (type == 3) + * -2: stored block length did not match one's complement + * -3: dynamic block code description: too many length or distance codes + * -4: dynamic block code description: code lengths codes incomplete + * -5: dynamic block code description: repeat lengths with no first length + * -6: dynamic block code description: repeat more than specified lengths + * -7: dynamic block code description: invalid literal/length code lengths + * -8: dynamic block code description: invalid distance code lengths + * -9: dynamic block code description: missing end-of-block code + * -10: invalid literal/length or distance code in fixed or dynamic block + * -11: distance is too far back in fixed or dynamic block + * + * Format notes: + * + * - Three bits are read for each block to determine the kind of block and + * whether or not it is the last block. Then the block is decoded and the + * process repeated if it was not the last block. + * + * - The leftover bits in the last byte of the deflate data after the last + * block (if it was a fixed or dynamic block) are undefined and have no + * expected values to check. + */ +int puff(unsigned char *dest, /* pointer to destination pointer */ + unsigned long *destlen, /* amount of output space */ + const unsigned char *source, /* pointer to source data pointer */ + unsigned long *sourcelen) /* amount of input available */ +{ + struct state s; /* input/output state */ + int last, type; /* block information */ + int err; /* return value */ + + /* initialize output state */ + s.out = dest; + s.outlen = *destlen; /* ignored if dest is NIL */ + s.outcnt = 0; + + /* initialize input state */ + s.in = source; + s.inlen = *sourcelen; + s.incnt = 0; + s.bitbuf = 0; + s.bitcnt = 0; + + /* return if bits() or decode() tries to read past available input */ + if (setjmp(s.env) != 0) /* if came back here via longjmp() */ + err = 2; /* then skip do-loop, return error */ + else { + /* process blocks until last block or error */ + do { + last = bits(&s, 1); /* one if last block */ + type = bits(&s, 2); /* block type 0..3 */ + err = type == 0 ? + stored(&s) : + (type == 1 ? + fixed(&s) : + (type == 2 ? + dynamic(&s) : + -1)); /* type == 3, invalid */ + if (err != 0) + break; /* return with error */ + } while (!last); + } + + /* update the lengths and return */ + if (err <= 0) { + *destlen = s.outcnt; + *sourcelen = s.incnt; + } + return err; +} diff --git a/libz/contrib/puff/puff.h b/libz/contrib/puff/puff.h new file mode 100644 index 000000000..e23a24543 --- /dev/null +++ b/libz/contrib/puff/puff.h @@ -0,0 +1,35 @@ +/* puff.h + Copyright (C) 2002-2013 Mark Adler, all rights reserved + version 2.3, 21 Jan 2013 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + + +/* + * See puff.c for purpose and usage. + */ +#ifndef NIL +# define NIL ((unsigned char *)0) /* for no output option */ +#endif + +int puff(unsigned char *dest, /* pointer to destination pointer */ + unsigned long *destlen, /* amount of output space */ + const unsigned char *source, /* pointer to source data pointer */ + unsigned long *sourcelen); /* amount of input available */ diff --git a/libz/contrib/puff/pufftest.c b/libz/contrib/puff/pufftest.c new file mode 100644 index 000000000..776481488 --- /dev/null +++ b/libz/contrib/puff/pufftest.c @@ -0,0 +1,165 @@ +/* + * pufftest.c + * Copyright (C) 2002-2013 Mark Adler + * For conditions of distribution and use, see copyright notice in puff.h + * version 2.3, 21 Jan 2013 + */ + +/* Example of how to use puff(). + + Usage: puff [-w] [-f] [-nnn] file + ... | puff [-w] [-f] [-nnn] + + where file is the input file with deflate data, nnn is the number of bytes + of input to skip before inflating (e.g. to skip a zlib or gzip header), and + -w is used to write the decompressed data to stdout. -f is for coverage + testing, and causes pufftest to fail with not enough output space (-f does + a write like -w, so -w is not required). */ + +#include +#include +#include "puff.h" + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#define local static + +/* Return size times approximately the cube root of 2, keeping the result as 1, + 3, or 5 times a power of 2 -- the result is always > size, until the result + is the maximum value of an unsigned long, where it remains. This is useful + to keep reallocations less than ~33% over the actual data. */ +local size_t bythirds(size_t size) +{ + int n; + size_t m; + + m = size; + for (n = 0; m; n++) + m >>= 1; + if (n < 3) + return size + 1; + n -= 3; + m = size >> n; + m += m == 6 ? 2 : 1; + m <<= n; + return m > size ? m : (size_t)(-1); +} + +/* Read the input file *name, or stdin if name is NULL, into allocated memory. + Reallocate to larger buffers until the entire file is read in. Return a + pointer to the allocated data, or NULL if there was a memory allocation + failure. *len is the number of bytes of data read from the input file (even + if load() returns NULL). If the input file was empty or could not be opened + or read, *len is zero. */ +local void *load(const char *name, size_t *len) +{ + size_t size; + void *buf, *swap; + FILE *in; + + *len = 0; + buf = malloc(size = 4096); + if (buf == NULL) + return NULL; + in = name == NULL ? stdin : fopen(name, "rb"); + if (in != NULL) { + for (;;) { + *len += fread((char *)buf + *len, 1, size - *len, in); + if (*len < size) break; + size = bythirds(size); + if (size == *len || (swap = realloc(buf, size)) == NULL) { + free(buf); + buf = NULL; + break; + } + buf = swap; + } + fclose(in); + } + return buf; +} + +int main(int argc, char **argv) +{ + int ret, put = 0, fail = 0; + unsigned skip = 0; + char *arg, *name = NULL; + unsigned char *source = NULL, *dest; + size_t len = 0; + unsigned long sourcelen, destlen; + + /* process arguments */ + while (arg = *++argv, --argc) + if (arg[0] == '-') { + if (arg[1] == 'w' && arg[2] == 0) + put = 1; + else if (arg[1] == 'f' && arg[2] == 0) + fail = 1, put = 1; + else if (arg[1] >= '0' && arg[1] <= '9') + skip = (unsigned)atoi(arg + 1); + else { + fprintf(stderr, "invalid option %s\n", arg); + return 3; + } + } + else if (name != NULL) { + fprintf(stderr, "only one file name allowed\n"); + return 3; + } + else + name = arg; + source = load(name, &len); + if (source == NULL) { + fprintf(stderr, "memory allocation failure\n"); + return 4; + } + if (len == 0) { + fprintf(stderr, "could not read %s, or it was empty\n", + name == NULL ? "" : name); + free(source); + return 3; + } + if (skip >= len) { + fprintf(stderr, "skip request of %d leaves no input\n", skip); + free(source); + return 3; + } + + /* test inflate data with offset skip */ + len -= skip; + sourcelen = (unsigned long)len; + ret = puff(NIL, &destlen, source + skip, &sourcelen); + if (ret) + fprintf(stderr, "puff() failed with return code %d\n", ret); + else { + fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen); + if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n", + len - sourcelen); + } + + /* if requested, inflate again and write decompressd data to stdout */ + if (put && ret == 0) { + if (fail) + destlen >>= 1; + dest = malloc(destlen); + if (dest == NULL) { + fprintf(stderr, "memory allocation failure\n"); + free(source); + return 4; + } + puff(dest, &destlen, source + skip, &sourcelen); + SET_BINARY_MODE(stdout); + fwrite(dest, 1, destlen, stdout); + free(dest); + } + + /* clean up */ + free(source); + return ret; +} diff --git a/libz/contrib/testzlib/testzlib.c b/libz/contrib/testzlib/testzlib.c new file mode 100644 index 000000000..5f659dea0 --- /dev/null +++ b/libz/contrib/testzlib/testzlib.c @@ -0,0 +1,275 @@ +#include +#include +#include + +#include "zlib.h" + + +void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B) +{ + R->HighPart = A.HighPart - B.HighPart; + if (A.LowPart >= B.LowPart) + R->LowPart = A.LowPart - B.LowPart; + else + { + R->LowPart = A.LowPart - B.LowPart; + R->HighPart --; + } +} + +#ifdef _M_X64 +// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc +unsigned __int64 __rdtsc(void); +void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) +{ + // printf("rdtsc = %I64x\n",__rdtsc()); + pbeginTime64->QuadPart=__rdtsc(); +} + +LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER LIres; + unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart)); + LIres.QuadPart=res; + // printf("rdtsc = %I64x\n",__rdtsc()); + return LIres; +} +#else +#ifdef _M_IX86 +void myGetRDTSC32(LARGE_INTEGER * pbeginTime64) +{ + DWORD dwEdx,dwEax; + _asm + { + rdtsc + mov dwEax,eax + mov dwEdx,edx + } + pbeginTime64->LowPart=dwEax; + pbeginTime64->HighPart=dwEdx; +} + +void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) +{ + myGetRDTSC32(pbeginTime64); +} + +LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER LIres,endTime64; + myGetRDTSC32(&endTime64); + + LIres.LowPart=LIres.HighPart=0; + MyDoMinus64(&LIres,endTime64,beginTime64); + return LIres; +} +#else +void myGetRDTSC32(LARGE_INTEGER * pbeginTime64) +{ +} + +void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64) +{ +} + +LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER lr; + lr.QuadPart=0; + return lr; +} +#endif +#endif + +void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf) +{ + if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64))) + { + pbeginTime64->LowPart = GetTickCount(); + pbeginTime64->HighPart = 0; + } +} + +DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf) +{ + LARGE_INTEGER endTime64,ticksPerSecond,ticks; + DWORDLONG ticksShifted,tickSecShifted; + DWORD dwLog=16+0; + DWORD dwRet; + if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64))) + dwRet = (GetTickCount() - beginTime64.LowPart)*1; + else + { + MyDoMinus64(&ticks,endTime64,beginTime64); + QueryPerformanceFrequency(&ticksPerSecond); + + + { + ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog); + tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog); + + } + + dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted)); + dwRet *=1; + } + return dwRet; +} + +int ReadFileMemory(const char* filename,long* plFileSize,unsigned char** pFilePtr) +{ + FILE* stream; + unsigned char* ptr; + int retVal=1; + stream=fopen(filename, "rb"); + if (stream==NULL) + return 0; + + fseek(stream,0,SEEK_END); + + *plFileSize=ftell(stream); + fseek(stream,0,SEEK_SET); + ptr=malloc((*plFileSize)+1); + if (ptr==NULL) + retVal=0; + else + { + if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize)) + retVal=0; + } + fclose(stream); + *pFilePtr=ptr; + return retVal; +} + +int main(int argc, char *argv[]) +{ + int BlockSizeCompress=0x8000; + int BlockSizeUncompress=0x8000; + int cprLevel=Z_DEFAULT_COMPRESSION ; + long lFileSize; + unsigned char* FilePtr; + long lBufferSizeCpr; + long lBufferSizeUncpr; + long lCompressedSize=0; + unsigned char* CprPtr; + unsigned char* UncprPtr; + long lSizeCpr,lSizeUncpr; + DWORD dwGetTick,dwMsecQP; + LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc; + + if (argc<=1) + { + printf("run TestZlib [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n"); + return 0; + } + + if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0) + { + printf("error reading %s\n",argv[1]); + return 1; + } + else printf("file %s read, %u bytes\n",argv[1],lFileSize); + + if (argc>=3) + BlockSizeCompress=atol(argv[2]); + + if (argc>=4) + BlockSizeUncompress=atol(argv[3]); + + if (argc>=5) + cprLevel=(int)atol(argv[4]); + + lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200; + lBufferSizeUncpr = lBufferSizeCpr; + + CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress); + + BeginCountPerfCounter(&li_qp,TRUE); + dwGetTick=GetTickCount(); + BeginCountRdtsc(&li_rdtsc); + { + z_stream zcpr; + int ret=Z_OK; + long lOrigToDo = lFileSize; + long lOrigDone = 0; + int step=0; + memset(&zcpr,0,sizeof(z_stream)); + deflateInit(&zcpr,cprLevel); + + zcpr.next_in = FilePtr; + zcpr.next_out = CprPtr; + + + do + { + long all_read_before = zcpr.total_in; + zcpr.avail_in = min(lOrigToDo,BlockSizeCompress); + zcpr.avail_out = BlockSizeCompress; + ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH); + lOrigDone += (zcpr.total_in-all_read_before); + lOrigToDo -= (zcpr.total_in-all_read_before); + step++; + } while (ret==Z_OK); + + lSizeCpr=zcpr.total_out; + deflateEnd(&zcpr); + dwGetTick=GetTickCount()-dwGetTick; + dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE); + dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE); + printf("total compress size = %u, in %u step\n",lSizeCpr,step); + printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.); + printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.); + printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart); + } + + CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr); + UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress); + + BeginCountPerfCounter(&li_qp,TRUE); + dwGetTick=GetTickCount(); + BeginCountRdtsc(&li_rdtsc); + { + z_stream zcpr; + int ret=Z_OK; + long lOrigToDo = lSizeCpr; + long lOrigDone = 0; + int step=0; + memset(&zcpr,0,sizeof(z_stream)); + inflateInit(&zcpr); + + zcpr.next_in = CprPtr; + zcpr.next_out = UncprPtr; + + + do + { + long all_read_before = zcpr.total_in; + zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress); + zcpr.avail_out = BlockSizeUncompress; + ret=inflate(&zcpr,Z_SYNC_FLUSH); + lOrigDone += (zcpr.total_in-all_read_before); + lOrigToDo -= (zcpr.total_in-all_read_before); + step++; + } while (ret==Z_OK); + + lSizeUncpr=zcpr.total_out; + inflateEnd(&zcpr); + dwGetTick=GetTickCount()-dwGetTick; + dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE); + dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE); + printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step); + printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.); + printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.); + printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart); + } + + if (lSizeUncpr==lFileSize) + { + if (memcmp(FilePtr,UncprPtr,lFileSize)==0) + printf("compare ok\n"); + + } + + return 0; +} diff --git a/libz/contrib/testzlib/testzlib.txt b/libz/contrib/testzlib/testzlib.txt new file mode 100644 index 000000000..62258f149 --- /dev/null +++ b/libz/contrib/testzlib/testzlib.txt @@ -0,0 +1,10 @@ +To build testzLib with Visual Studio 2005: + +copy to a directory file from : +- root of zLib tree +- contrib/testzlib +- contrib/masmx86 +- contrib/masmx64 +- contrib/vstudio/vc7 + +and open testzlib8.sln \ No newline at end of file diff --git a/libz/contrib/untgz/Makefile.msc b/libz/contrib/untgz/Makefile.msc new file mode 100644 index 000000000..77b860221 --- /dev/null +++ b/libz/contrib/untgz/Makefile.msc @@ -0,0 +1,17 @@ +CC=cl +CFLAGS=-MD + +untgz.exe: untgz.obj ..\..\zlib.lib + $(CC) $(CFLAGS) untgz.obj ..\..\zlib.lib + +untgz.obj: untgz.c ..\..\zlib.h + $(CC) $(CFLAGS) -c -I..\.. untgz.c + +..\..\zlib.lib: + cd ..\.. + $(MAKE) -f win32\makefile.msc + cd contrib\untgz + +clean: + -del untgz.obj + -del untgz.exe diff --git a/libz/contrib/untgz/untgz.c b/libz/contrib/untgz/untgz.c new file mode 100644 index 000000000..2c391e598 --- /dev/null +++ b/libz/contrib/untgz/untgz.c @@ -0,0 +1,674 @@ +/* + * untgz.c -- Display contents and extract files from a gzip'd TAR file + * + * written by Pedro A. Aranda Gutierrez + * adaptation to Unix by Jean-loup Gailly + * various fixes by Cosmin Truta + */ + +#include +#include +#include +#include +#include + +#include "zlib.h" + +#ifdef unix +# include +#else +# include +# include +#endif + +#ifdef WIN32 +#include +# ifndef F_OK +# define F_OK 0 +# endif +# define mkdir(dirname,mode) _mkdir(dirname) +# ifdef _MSC_VER +# define access(path,mode) _access(path,mode) +# define chmod(path,mode) _chmod(path,mode) +# define strdup(str) _strdup(str) +# endif +#else +# include +#endif + + +/* values used in typeflag field */ + +#define REGTYPE '0' /* regular file */ +#define AREGTYPE '\0' /* regular file */ +#define LNKTYPE '1' /* link */ +#define SYMTYPE '2' /* reserved */ +#define CHRTYPE '3' /* character special */ +#define BLKTYPE '4' /* block special */ +#define DIRTYPE '5' /* directory */ +#define FIFOTYPE '6' /* FIFO special */ +#define CONTTYPE '7' /* reserved */ + +/* GNU tar extensions */ + +#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */ +#define GNUTYPE_LONGLINK 'K' /* long link name */ +#define GNUTYPE_LONGNAME 'L' /* long file name */ +#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */ +#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */ +#define GNUTYPE_SPARSE 'S' /* sparse file */ +#define GNUTYPE_VOLHDR 'V' /* tape/volume header */ + + +/* tar header */ + +#define BLOCKSIZE 512 +#define SHORTNAMESIZE 100 + +struct tar_header +{ /* byte offset */ + char name[100]; /* 0 */ + char mode[8]; /* 100 */ + char uid[8]; /* 108 */ + char gid[8]; /* 116 */ + char size[12]; /* 124 */ + char mtime[12]; /* 136 */ + char chksum[8]; /* 148 */ + char typeflag; /* 156 */ + char linkname[100]; /* 157 */ + char magic[6]; /* 257 */ + char version[2]; /* 263 */ + char uname[32]; /* 265 */ + char gname[32]; /* 297 */ + char devmajor[8]; /* 329 */ + char devminor[8]; /* 337 */ + char prefix[155]; /* 345 */ + /* 500 */ +}; + +union tar_buffer +{ + char buffer[BLOCKSIZE]; + struct tar_header header; +}; + +struct attr_item +{ + struct attr_item *next; + char *fname; + int mode; + time_t time; +}; + +enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID }; + +char *TGZfname OF((const char *)); +void TGZnotfound OF((const char *)); + +int getoct OF((char *, int)); +char *strtime OF((time_t *)); +int setfiletime OF((char *, time_t)); +void push_attr OF((struct attr_item **, char *, int, time_t)); +void restore_attr OF((struct attr_item **)); + +int ExprMatch OF((char *, char *)); + +int makedir OF((char *)); +int matchname OF((int, int, char **, char *)); + +void error OF((const char *)); +int tar OF((gzFile, int, int, int, char **)); + +void help OF((int)); +int main OF((int, char **)); + +char *prog; + +const char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL }; + +/* return the file name of the TGZ archive */ +/* or NULL if it does not exist */ + +char *TGZfname (const char *arcname) +{ + static char buffer[1024]; + int origlen,i; + + strcpy(buffer,arcname); + origlen = strlen(buffer); + + for (i=0; TGZsuffix[i]; i++) + { + strcpy(buffer+origlen,TGZsuffix[i]); + if (access(buffer,F_OK) == 0) + return buffer; + } + return NULL; +} + + +/* error message for the filename */ + +void TGZnotfound (const char *arcname) +{ + int i; + + fprintf(stderr,"%s: Couldn't find ",prog); + for (i=0;TGZsuffix[i];i++) + fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n", + arcname, + TGZsuffix[i]); + exit(1); +} + + +/* convert octal digits to int */ +/* on error return -1 */ + +int getoct (char *p,int width) +{ + int result = 0; + char c; + + while (width--) + { + c = *p++; + if (c == 0) + break; + if (c == ' ') + continue; + if (c < '0' || c > '7') + return -1; + result = result * 8 + (c - '0'); + } + return result; +} + + +/* convert time_t to string */ +/* use the "YYYY/MM/DD hh:mm:ss" format */ + +char *strtime (time_t *t) +{ + struct tm *local; + static char result[32]; + + local = localtime(t); + sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d", + local->tm_year+1900, local->tm_mon+1, local->tm_mday, + local->tm_hour, local->tm_min, local->tm_sec); + return result; +} + + +/* set file time */ + +int setfiletime (char *fname,time_t ftime) +{ +#ifdef WIN32 + static int isWinNT = -1; + SYSTEMTIME st; + FILETIME locft, modft; + struct tm *loctm; + HANDLE hFile; + int result; + + loctm = localtime(&ftime); + if (loctm == NULL) + return -1; + + st.wYear = (WORD)loctm->tm_year + 1900; + st.wMonth = (WORD)loctm->tm_mon + 1; + st.wDayOfWeek = (WORD)loctm->tm_wday; + st.wDay = (WORD)loctm->tm_mday; + st.wHour = (WORD)loctm->tm_hour; + st.wMinute = (WORD)loctm->tm_min; + st.wSecond = (WORD)loctm->tm_sec; + st.wMilliseconds = 0; + if (!SystemTimeToFileTime(&st, &locft) || + !LocalFileTimeToFileTime(&locft, &modft)) + return -1; + + if (isWinNT < 0) + isWinNT = (GetVersion() < 0x80000000) ? 1 : 0; + hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0), + NULL); + if (hFile == INVALID_HANDLE_VALUE) + return -1; + result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1; + CloseHandle(hFile); + return result; +#else + struct utimbuf settime; + + settime.actime = settime.modtime = ftime; + return utime(fname,&settime); +#endif +} + + +/* push file attributes */ + +void push_attr(struct attr_item **list,char *fname,int mode,time_t time) +{ + struct attr_item *item; + + item = (struct attr_item *)malloc(sizeof(struct attr_item)); + if (item == NULL) + error("Out of memory"); + item->fname = strdup(fname); + item->mode = mode; + item->time = time; + item->next = *list; + *list = item; +} + + +/* restore file attributes */ + +void restore_attr(struct attr_item **list) +{ + struct attr_item *item, *prev; + + for (item = *list; item != NULL; ) + { + setfiletime(item->fname,item->time); + chmod(item->fname,item->mode); + prev = item; + item = item->next; + free(prev); + } + *list = NULL; +} + + +/* match regular expression */ + +#define ISSPECIAL(c) (((c) == '*') || ((c) == '/')) + +int ExprMatch (char *string,char *expr) +{ + while (1) + { + if (ISSPECIAL(*expr)) + { + if (*expr == '/') + { + if (*string != '\\' && *string != '/') + return 0; + string ++; expr++; + } + else if (*expr == '*') + { + if (*expr ++ == 0) + return 1; + while (*++string != *expr) + if (*string == 0) + return 0; + } + } + else + { + if (*string != *expr) + return 0; + if (*expr++ == 0) + return 1; + string++; + } + } +} + + +/* recursive mkdir */ +/* abort on ENOENT; ignore other errors like "directory already exists" */ +/* return 1 if OK */ +/* 0 on error */ + +int makedir (char *newdir) +{ + char *buffer = strdup(newdir); + char *p; + int len = strlen(buffer); + + if (len <= 0) { + free(buffer); + return 0; + } + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mkdir(buffer, 0755) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT)) + { + fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + + +int matchname (int arg,int argc,char **argv,char *fname) +{ + if (arg == argc) /* no arguments given (untgz tgzarchive) */ + return 1; + + while (arg < argc) + if (ExprMatch(fname,argv[arg++])) + return 1; + + return 0; /* ignore this for the moment being */ +} + + +/* tar file list or extract */ + +int tar (gzFile in,int action,int arg,int argc,char **argv) +{ + union tar_buffer buffer; + int len; + int err; + int getheader = 1; + int remaining = 0; + FILE *outfile = NULL; + char fname[BLOCKSIZE]; + int tarmode; + time_t tartime; + struct attr_item *attributes = NULL; + + if (action == TGZ_LIST) + printf(" date time size file\n" + " ---------- -------- --------- -------------------------------------\n"); + while (1) + { + len = gzread(in, &buffer, BLOCKSIZE); + if (len < 0) + error(gzerror(in, &err)); + /* + * Always expect complete blocks to process + * the tar information. + */ + if (len != BLOCKSIZE) + { + action = TGZ_INVALID; /* force error exit */ + remaining = 0; /* force I/O cleanup */ + } + + /* + * If we have to get a tar header + */ + if (getheader >= 1) + { + /* + * if we met the end of the tar + * or the end-of-tar block, + * we are done + */ + if (len == 0 || buffer.header.name[0] == 0) + break; + + tarmode = getoct(buffer.header.mode,8); + tartime = (time_t)getoct(buffer.header.mtime,12); + if (tarmode == -1 || tartime == (time_t)-1) + { + buffer.header.name[0] = 0; + action = TGZ_INVALID; + } + + if (getheader == 1) + { + strncpy(fname,buffer.header.name,SHORTNAMESIZE); + if (fname[SHORTNAMESIZE-1] != 0) + fname[SHORTNAMESIZE] = 0; + } + else + { + /* + * The file name is longer than SHORTNAMESIZE + */ + if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0) + error("bad long name"); + getheader = 1; + } + + /* + * Act according to the type flag + */ + switch (buffer.header.typeflag) + { + case DIRTYPE: + if (action == TGZ_LIST) + printf(" %s %s\n",strtime(&tartime),fname); + if (action == TGZ_EXTRACT) + { + makedir(fname); + push_attr(&attributes,fname,tarmode,tartime); + } + break; + case REGTYPE: + case AREGTYPE: + remaining = getoct(buffer.header.size,12); + if (remaining == -1) + { + action = TGZ_INVALID; + break; + } + if (action == TGZ_LIST) + printf(" %s %9d %s\n",strtime(&tartime),remaining,fname); + else if (action == TGZ_EXTRACT) + { + if (matchname(arg,argc,argv,fname)) + { + outfile = fopen(fname,"wb"); + if (outfile == NULL) { + /* try creating directory */ + char *p = strrchr(fname, '/'); + if (p != NULL) { + *p = '\0'; + makedir(fname); + *p = '/'; + outfile = fopen(fname,"wb"); + } + } + if (outfile != NULL) + printf("Extracting %s\n",fname); + else + fprintf(stderr, "%s: Couldn't create %s",prog,fname); + } + else + outfile = NULL; + } + getheader = 0; + break; + case GNUTYPE_LONGLINK: + case GNUTYPE_LONGNAME: + remaining = getoct(buffer.header.size,12); + if (remaining < 0 || remaining >= BLOCKSIZE) + { + action = TGZ_INVALID; + break; + } + len = gzread(in, fname, BLOCKSIZE); + if (len < 0) + error(gzerror(in, &err)); + if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining) + { + action = TGZ_INVALID; + break; + } + getheader = 2; + break; + default: + if (action == TGZ_LIST) + printf(" %s <---> %s\n",strtime(&tartime),fname); + break; + } + } + else + { + unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining; + + if (outfile != NULL) + { + if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) + { + fprintf(stderr, + "%s: Error writing %s -- skipping\n",prog,fname); + fclose(outfile); + outfile = NULL; + remove(fname); + } + } + remaining -= bytes; + } + + if (remaining == 0) + { + getheader = 1; + if (outfile != NULL) + { + fclose(outfile); + outfile = NULL; + if (action != TGZ_INVALID) + push_attr(&attributes,fname,tarmode,tartime); + } + } + + /* + * Abandon if errors are found + */ + if (action == TGZ_INVALID) + { + error("broken archive"); + break; + } + } + + /* + * Restore file modes and time stamps + */ + restore_attr(&attributes); + + if (gzclose(in) != Z_OK) + error("failed gzclose"); + + return 0; +} + + +/* ============================================================ */ + +void help(int exitval) +{ + printf("untgz version 0.2.1\n" + " using zlib version %s\n\n", + zlibVersion()); + printf("Usage: untgz file.tgz extract all files\n" + " untgz file.tgz fname ... extract selected files\n" + " untgz -l file.tgz list archive contents\n" + " untgz -h display this help\n"); + exit(exitval); +} + +void error(const char *msg) +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + + +/* ============================================================ */ + +#if defined(WIN32) && defined(__GNUC__) +int _CRT_glob = 0; /* disable argument globbing in MinGW */ +#endif + +int main(int argc,char **argv) +{ + int action = TGZ_EXTRACT; + int arg = 1; + char *TGZfile; + gzFile *f; + + prog = strrchr(argv[0],'\\'); + if (prog == NULL) + { + prog = strrchr(argv[0],'/'); + if (prog == NULL) + { + prog = strrchr(argv[0],':'); + if (prog == NULL) + prog = argv[0]; + else + prog++; + } + else + prog++; + } + else + prog++; + + if (argc == 1) + help(0); + + if (strcmp(argv[arg],"-l") == 0) + { + action = TGZ_LIST; + if (argc == ++arg) + help(0); + } + else if (strcmp(argv[arg],"-h") == 0) + { + help(0); + } + + if ((TGZfile = TGZfname(argv[arg])) == NULL) + TGZnotfound(argv[arg]); + + ++arg; + if ((action == TGZ_LIST) && (arg != argc)) + help(1); + +/* + * Process the TGZ file + */ + switch(action) + { + case TGZ_LIST: + case TGZ_EXTRACT: + f = gzopen(TGZfile,"rb"); + if (f == NULL) + { + fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile); + return 1; + } + exit(tar(f, action, arg, argc, argv)); + break; + + default: + error("Unknown option"); + exit(1); + } + + return 0; +} diff --git a/libz/contrib/vstudio/readme.txt b/libz/contrib/vstudio/readme.txt new file mode 100644 index 000000000..bfdcd9dd0 --- /dev/null +++ b/libz/contrib/vstudio/readme.txt @@ -0,0 +1,65 @@ +Building instructions for the DLL versions of Zlib 1.2.8 +======================================================== + +This directory contains projects that build zlib and minizip using +Microsoft Visual C++ 9.0/10.0. + +You don't need to build these projects yourself. You can download the +binaries from: + http://www.winimage.com/zLibDll + +More information can be found at this site. + + + + + +Build instructions for Visual Studio 2008 (32 bits or 64 bits) +-------------------------------------------------------------- +- Uncompress current zlib, including all contrib/* files +- Compile assembly code (with Visual Studio Command Prompt) by running: + bld_ml64.bat (in contrib\masmx64) + bld_ml32.bat (in contrib\masmx86) +- Open contrib\vstudio\vc9\zlibvc.sln with Microsoft Visual C++ 2008 +- Or run: vcbuild /rebuild contrib\vstudio\vc9\zlibvc.sln "Release|Win32" + +Build instructions for Visual Studio 2010 (32 bits or 64 bits) +-------------------------------------------------------------- +- Uncompress current zlib, including all contrib/* files +- Open contrib\vstudio\vc10\zlibvc.sln with Microsoft Visual C++ 2010 + +Build instructions for Visual Studio 2012 (32 bits or 64 bits) +-------------------------------------------------------------- +- Uncompress current zlib, including all contrib/* files +- Open contrib\vstudio\vc11\zlibvc.sln with Microsoft Visual C++ 2012 + + +Important +--------- +- To use zlibwapi.dll in your application, you must define the + macro ZLIB_WINAPI when compiling your application's source files. + + +Additional notes +---------------- +- This DLL, named zlibwapi.dll, is compatible to the old zlib.dll built + by Gilles Vollant from the zlib 1.1.x sources, and distributed at + http://www.winimage.com/zLibDll + It uses the WINAPI calling convention for the exported functions, and + includes the minizip functionality. If your application needs that + particular build of zlib.dll, you can rename zlibwapi.dll to zlib.dll. + +- The new DLL was renamed because there exist several incompatible + versions of zlib.dll on the Internet. + +- There is also an official DLL build of zlib, named zlib1.dll. This one + is exporting the functions using the CDECL convention. See the file + win32\DLL_FAQ.txt found in this zlib distribution. + +- There used to be a ZLIB_DLL macro in zlib 1.1.x, but now this symbol + has a slightly different effect. To avoid compatibility problems, do + not define it here. + + +Gilles Vollant +info@winimage.com diff --git a/libz/contrib/vstudio/vc10/miniunz.vcxproj b/libz/contrib/vstudio/vc10/miniunz.vcxproj new file mode 100644 index 000000000..74e15c90d --- /dev/null +++ b/libz/contrib/vstudio/vc10/miniunz.vcxproj @@ -0,0 +1,310 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694382A} + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + true + false + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + false + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + true + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + true + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + false + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + $(IntDir) + Level3 + EditAndContinue + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/miniunz.vcxproj.filters b/libz/contrib/vstudio/vc10/miniunz.vcxproj.filters new file mode 100644 index 000000000..0b2a3de2d --- /dev/null +++ b/libz/contrib/vstudio/vc10/miniunz.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {048af943-022b-4db6-beeb-a54c34774ee2} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {c1d600d2-888f-4aea-b73e-8b0dd9befa0c} + h;hpp;hxx;hm;inl;inc + + + {0844199a-966b-4f19-81db-1e0125e141b9} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/minizip.vcxproj b/libz/contrib/vstudio/vc10/minizip.vcxproj new file mode 100644 index 000000000..917e15652 --- /dev/null +++ b/libz/contrib/vstudio/vc10/minizip.vcxproj @@ -0,0 +1,307 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B} + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + true + false + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + false + x64\$(Configuration)\ + x64\$(Configuration)\ + true + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + true + false + x64\$(Configuration)\ + x64\$(Configuration)\ + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + $(IntDir) + Level3 + EditAndContinue + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/minizip.vcxproj.filters b/libz/contrib/vstudio/vc10/minizip.vcxproj.filters new file mode 100644 index 000000000..dd73cd313 --- /dev/null +++ b/libz/contrib/vstudio/vc10/minizip.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {c0419b40-bf50-40da-b153-ff74215b79de} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {bb87b070-735b-478e-92ce-7383abb2f36c} + h;hpp;hxx;hm;inl;inc + + + {f46ab6a6-548f-43cb-ae96-681abb5bd5db} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/testzlib.vcxproj b/libz/contrib/vstudio/vc10/testzlib.vcxproj new file mode 100644 index 000000000..9088d176f --- /dev/null +++ b/libz/contrib/vstudio/vc10/testzlib.vcxproj @@ -0,0 +1,420 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B} + testzlib + Win32Proj + + + + Application + MultiByte + true + + + Application + MultiByte + true + + + Application + MultiByte + + + Application + MultiByte + true + + + Application + MultiByte + true + + + Application + MultiByte + + + Application + true + + + Application + true + + + Application + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + true + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + true + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + EditAndContinue + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/testzlib.vcxproj.filters b/libz/contrib/vstudio/vc10/testzlib.vcxproj.filters new file mode 100644 index 000000000..249daa89c --- /dev/null +++ b/libz/contrib/vstudio/vc10/testzlib.vcxproj.filters @@ -0,0 +1,58 @@ + + + + + {c1f6a2e3-5da5-4955-8653-310d3efe05a9} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {c2aaffdc-2c95-4d6f-8466-4bec5890af2c} + h;hpp;hxx;hm;inl;inc + + + {c274fe07-05f2-461c-964b-f6341e4e7eb5} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/testzlibdll.vcxproj b/libz/contrib/vstudio/vc10/testzlibdll.vcxproj new file mode 100644 index 000000000..bcb08ff95 --- /dev/null +++ b/libz/contrib/vstudio/vc10/testzlibdll.vcxproj @@ -0,0 +1,310 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694366A} + Win32Proj + + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + true + false + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + false + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + true + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + true + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + false + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebug + false + + + $(IntDir) + Level3 + EditAndContinue + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/testzlibdll.vcxproj.filters b/libz/contrib/vstudio/vc10/testzlibdll.vcxproj.filters new file mode 100644 index 000000000..53a8693bb --- /dev/null +++ b/libz/contrib/vstudio/vc10/testzlibdll.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {fa61a89f-93fc-4c89-b29e-36224b7592f4} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {d4b85da0-2ba2-4934-b57f-e2584e3848ee} + h;hpp;hxx;hm;inl;inc + + + {e573e075-00bd-4a7d-bd67-a8cc9bfc5aca} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/zlib.rc b/libz/contrib/vstudio/vc10/zlib.rc new file mode 100644 index 000000000..73f6476d6 --- /dev/null +++ b/libz/contrib/vstudio/vc10/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1,2,8,0 + PRODUCTVERSION 1,2,8,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.8\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlibwapi.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/libz/contrib/vstudio/vc10/zlibstat.vcxproj b/libz/contrib/vstudio/vc10/zlibstat.vcxproj new file mode 100644 index 000000000..b9f2bbe5f --- /dev/null +++ b/libz/contrib/vstudio/vc10/zlibstat.vcxproj @@ -0,0 +1,473 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} + + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + + + MultiThreadedDebug + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + Itanium + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/zlibstat.vcxproj.filters b/libz/contrib/vstudio/vc10/zlibstat.vcxproj.filters new file mode 100644 index 000000000..c8c7f7ea3 --- /dev/null +++ b/libz/contrib/vstudio/vc10/zlibstat.vcxproj.filters @@ -0,0 +1,77 @@ + + + + + {174213f6-7f66-4ae8-a3a8-a1e0a1e6ffdd} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/zlibvc.def b/libz/contrib/vstudio/vc10/zlibvc.def new file mode 100644 index 000000000..636704672 --- /dev/null +++ b/libz/contrib/vstudio/vc10/zlibvc.def @@ -0,0 +1,143 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.2.8 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + inflateResetKeep @163 + deflateResetKeep @164 + +; zlib1 v1.2.7 added: + gzopen_w @165 + +; zlib1 v1.2.8 added: + inflateGetDictionary @166 + gzvprintf @167 diff --git a/libz/contrib/vstudio/vc10/zlibvc.sln b/libz/contrib/vstudio/vc10/zlibvc.sln new file mode 100644 index 000000000..6f6ffd5ee --- /dev/null +++ b/libz/contrib/vstudio/vc10/zlibvc.sln @@ -0,0 +1,135 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libz/contrib/vstudio/vc10/zlibvc.vcxproj b/libz/contrib/vstudio/vc10/zlibvc.vcxproj new file mode 100644 index 000000000..6ff9ddb07 --- /dev/null +++ b/libz/contrib/vstudio/vc10/zlibvc.vcxproj @@ -0,0 +1,657 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {8FD826F8-3739-44E6-8CC8-997122E53B8D} + + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + true + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + true + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + true + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + zlibwapid + zlibwapi + zlibwapi + zlibwapid + zlibwapi + zlibwapi + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + + + MultiThreadedDebug + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + true + .\zlibvc.def + true + true + Windows + false + + + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + true + false + .\zlibvc.def + true + Windows + false + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + true + false + .\zlibvc.def + true + Windows + false + + + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + true + .\zlibvc.def + true + true + Windows + MachineX64 + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + true + false + .\zlibvc.def + true + Windows + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + true + false + .\zlibvc.def + true + Windows + MachineX64 + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc10/zlibvc.vcxproj.filters b/libz/contrib/vstudio/vc10/zlibvc.vcxproj.filters new file mode 100644 index 000000000..180b71cd6 --- /dev/null +++ b/libz/contrib/vstudio/vc10/zlibvc.vcxproj.filters @@ -0,0 +1,118 @@ + + + + + {07934a85-8b61-443d-a0ee-b2eedb74f3cd} + cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90 + + + {1d99675b-433d-4a21-9e50-ed4ab8b19762} + h;hpp;hxx;hm;inl;fi;fd + + + {431c0958-fa71-44d0-9084-2d19d100c0cc} + ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc11/miniunz.vcxproj b/libz/contrib/vstudio/vc11/miniunz.vcxproj new file mode 100644 index 000000000..ca57522a7 --- /dev/null +++ b/libz/contrib/vstudio/vc11/miniunz.vcxproj @@ -0,0 +1,314 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694382A} + Win32Proj + + + + Application + MultiByte + v120 + + + Application + Unicode + v120 + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + true + false + x86\MiniUnzip$(Configuration)\ + x86\MiniUnzip$(Configuration)\Tmp\ + false + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + true + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + true + false + x64\MiniUnzip$(Configuration)\ + x64\MiniUnzip$(Configuration)\Tmp\ + false + false + ia64\MiniUnzip$(Configuration)\ + ia64\MiniUnzip$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + $(OutDir)miniunz.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)miniunz.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc11/minizip.vcxproj b/libz/contrib/vstudio/vc11/minizip.vcxproj new file mode 100644 index 000000000..885bda7c3 --- /dev/null +++ b/libz/contrib/vstudio/vc11/minizip.vcxproj @@ -0,0 +1,311 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B} + Win32Proj + + + + Application + MultiByte + v120 + + + Application + Unicode + v120 + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + true + false + x86\MiniZip$(Configuration)\ + x86\MiniZip$(Configuration)\Tmp\ + false + x64\$(Configuration)\ + x64\$(Configuration)\ + true + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + true + false + x64\$(Configuration)\ + x64\$(Configuration)\ + false + ia64\$(Configuration)\ + ia64\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + $(OutDir)minizip.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)minizip.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc11/testzlib.vcxproj b/libz/contrib/vstudio/vc11/testzlib.vcxproj new file mode 100644 index 000000000..63b2cea91 --- /dev/null +++ b/libz/contrib/vstudio/vc11/testzlib.vcxproj @@ -0,0 +1,426 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B} + testzlib + Win32Proj + + + + Application + MultiByte + true + v120 + + + Application + MultiByte + true + v120 + + + Application + Unicode + v120 + + + Application + MultiByte + true + + + Application + MultiByte + true + + + Application + MultiByte + + + Application + true + v120 + + + Application + true + v120 + + + Application + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + true + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x86\TestZlib$(Configuration)\ + x86\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + true + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + x64\TestZlib$(Configuration)\ + x64\TestZlib$(Configuration)\Tmp\ + false + ia64\TestZlib$(Configuration)\ + ia64\TestZlib$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)testzlib.exe + true + Console + true + true + false + + + MachineX86 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDebugDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + Disabled + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + AssemblyAndSourceCode + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + %(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + ..\..\..;%(AdditionalIncludeDirectories) + ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + false + $(IntDir) + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + $(OutDir)testzlib.exe + true + Console + true + true + MachineIA64 + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc11/testzlibdll.vcxproj b/libz/contrib/vstudio/vc11/testzlibdll.vcxproj new file mode 100644 index 000000000..61f81421f --- /dev/null +++ b/libz/contrib/vstudio/vc11/testzlibdll.vcxproj @@ -0,0 +1,314 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {C52F9E7B-498A-42BE-8DB4-85A15694366A} + Win32Proj + + + + Application + MultiByte + v120 + + + Application + Unicode + v120 + + + Application + MultiByte + + + Application + MultiByte + + + Application + MultiByte + v120 + + + Application + MultiByte + v120 + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + true + false + x86\TestZlibDll$(Configuration)\ + x86\TestZlibDll$(Configuration)\Tmp\ + false + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + true + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + true + false + x64\TestZlibDll$(Configuration)\ + x64\TestZlibDll$(Configuration)\Tmp\ + false + false + ia64\TestZlibDll$(Configuration)\ + ia64\TestZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + false + + + MachineX86 + + + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Default + MultiThreaded + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineX64 + + + + + Itanium + + + Disabled + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDebugDLL + false + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + $(OutDir)testzlib.pdb + Console + MachineIA64 + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineX64 + + + + + Itanium + + + MaxSpeed + OnlyExplicitInline + true + ..\..\..;..\..\minizip;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions) + true + Default + MultiThreadedDLL + false + true + + + $(IntDir) + Level3 + ProgramDatabase + + + ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies) + $(OutDir)testzlibdll.exe + true + Console + true + true + MachineIA64 + + + + + + + + {8fd826f8-3739-44e6-8cc8-997122e53b8d} + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc11/zlib.rc b/libz/contrib/vstudio/vc11/zlib.rc new file mode 100644 index 000000000..73f6476d6 --- /dev/null +++ b/libz/contrib/vstudio/vc11/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1,2,8,0 + PRODUCTVERSION 1,2,8,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.8\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlibwapi.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/libz/contrib/vstudio/vc11/zlibstat.vcxproj b/libz/contrib/vstudio/vc11/zlibstat.vcxproj new file mode 100644 index 000000000..1cd2cacd7 --- /dev/null +++ b/libz/contrib/vstudio/vc11/zlibstat.vcxproj @@ -0,0 +1,464 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8} + + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + Unicode + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + + + StaticLibrary + false + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x86\ZlibStat$(Configuration)\ + x86\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + x64\ZlibStat$(Configuration)\ + x64\ZlibStat$(Configuration)\Tmp\ + ia64\ZlibStat$(Configuration)\ + ia64\ZlibStat$(Configuration)\Tmp\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + OldStyle + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + X64 + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + Itanium + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibstat.pch + $(IntDir) + $(IntDir) + $(OutDir) + Level3 + true + + + 0x040c + + + /MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions) + $(OutDir)zlibstat.lib + true + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc11/zlibvc.def b/libz/contrib/vstudio/vc11/zlibvc.def new file mode 100644 index 000000000..db52cf187 --- /dev/null +++ b/libz/contrib/vstudio/vc11/zlibvc.def @@ -0,0 +1,143 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.28 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + inflateResetKeep @163 + deflateResetKeep @164 + +; zlib1 v1.2.7 added: + gzopen_w @165 + +; zlib1 v1.2.8 added: + inflateGetDictionary @166 + gzvprintf @167 diff --git a/libz/contrib/vstudio/vc11/zlibvc.sln b/libz/contrib/vstudio/vc11/zlibvc.sln new file mode 100644 index 000000000..9fcbafdd0 --- /dev/null +++ b/libz/contrib/vstudio/vc11/zlibvc.sln @@ -0,0 +1,117 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libz/contrib/vstudio/vc11/zlibvc.vcxproj b/libz/contrib/vstudio/vc11/zlibvc.vcxproj new file mode 100644 index 000000000..4775fdd87 --- /dev/null +++ b/libz/contrib/vstudio/vc11/zlibvc.vcxproj @@ -0,0 +1,695 @@ + + + + + Debug + Itanium + + + Debug + Win32 + + + Debug + x64 + + + ReleaseWithoutAsm + Itanium + + + ReleaseWithoutAsm + Win32 + + + ReleaseWithoutAsm + x64 + + + Release + Itanium + + + Release + Win32 + + + Release + x64 + + + + {8FD826F8-3739-44E6-8CC8-997122E53B8D} + libz + + + + StaticLibrary + false + true + v120 + + + DynamicLibrary + false + true + v120 + + + StaticLibrary + false + v120 + Unicode + + + DynamicLibrary + false + true + + + DynamicLibrary + false + true + + + DynamicLibrary + false + + + DynamicLibrary + false + true + v120 + + + DynamicLibrary + false + true + v120 + + + DynamicLibrary + false + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + $(Configuration)_lib\ + $(Configuration)_lib\Tmp\ + true + false + x86\ZlibDll$(Configuration)\ + x86\ZlibDll$(Configuration)\Tmp\ + false + false + $(Configuration)_lib\ + $(Configuration)_lib\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + true + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + true + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + x64\ZlibDll$(Configuration)\ + x64\ZlibDll$(Configuration)\Tmp\ + false + false + ia64\ZlibDll$(Configuration)\ + ia64\ZlibDll$(Configuration)\Tmp\ + false + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + zlibd + zlibwapi + zlib + zlibwapi + zlibwapi + zlibwapi + + + .lib + + + .lib + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions) + true + + + MultiThreaded + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + /MACHINE:I386 %(AdditionalOptions) + ..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + false + + + $(OutDir)zlibwapi.lib + + + cd ..\..\masmx86 +bld_ml32.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + cd ..\..\contrib\masmx64 +bld_ml64.bat + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + Disabled + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + + + MultiThreadedDebugDLL + false + $(IntDir)zlibvc.pch + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + .\zlibvc.def + true + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + ..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies) + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineX64 + + + cd ..\..\masmx64 +bld_ml64.bat + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Itanium + $(OutDir)zlibvc.tlb + + + OnlyExplicitInline + ..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories) + _CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + $(IntDir)zlibvc.pch + All + $(IntDir) + $(IntDir) + $(OutDir) + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)zlibwapi.dll + true + false + .\zlibvc.def + $(OutDir)zlibwapi.pdb + true + $(OutDir)zlibwapi.map + Windows + $(OutDir)zlibwapi.lib + MachineIA64 + + + + + + + + + + + + + + true + true + true + true + true + true + + + + + + + + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + ZLIB_INTERNAL;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libz/contrib/vstudio/vc9/miniunz.vcproj b/libz/contrib/vstudio/vc9/miniunz.vcproj new file mode 100644 index 000000000..7da32b91e --- /dev/null +++ b/libz/contrib/vstudio/vc9/miniunz.vcproj @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libz/contrib/vstudio/vc9/minizip.vcproj b/libz/contrib/vstudio/vc9/minizip.vcproj new file mode 100644 index 000000000..e57e07d90 --- /dev/null +++ b/libz/contrib/vstudio/vc9/minizip.vcproj @@ -0,0 +1,562 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libz/contrib/vstudio/vc9/testzlib.vcproj b/libz/contrib/vstudio/vc9/testzlib.vcproj new file mode 100644 index 000000000..9cb0bf877 --- /dev/null +++ b/libz/contrib/vstudio/vc9/testzlib.vcproj @@ -0,0 +1,852 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libz/contrib/vstudio/vc9/testzlibdll.vcproj b/libz/contrib/vstudio/vc9/testzlibdll.vcproj new file mode 100644 index 000000000..b1ddde05f --- /dev/null +++ b/libz/contrib/vstudio/vc9/testzlibdll.vcproj @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libz/contrib/vstudio/vc9/zlib.rc b/libz/contrib/vstudio/vc9/zlib.rc new file mode 100644 index 000000000..73f6476d6 --- /dev/null +++ b/libz/contrib/vstudio/vc9/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1,2,8,0 + PRODUCTVERSION 1,2,8,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0" + VALUE "FileVersion", "1.2.8\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlibwapi.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/libz/contrib/vstudio/vc9/zlibstat.vcproj b/libz/contrib/vstudio/vc9/zlibstat.vcproj new file mode 100644 index 000000000..61c76c7c5 --- /dev/null +++ b/libz/contrib/vstudio/vc9/zlibstat.vcproj @@ -0,0 +1,835 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libz/contrib/vstudio/vc9/zlibvc.def b/libz/contrib/vstudio/vc9/zlibvc.def new file mode 100644 index 000000000..636704672 --- /dev/null +++ b/libz/contrib/vstudio/vc9/zlibvc.def @@ -0,0 +1,143 @@ +LIBRARY +; zlib data compression and ZIP file I/O library + +VERSION 1.2.8 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + deflatePending @52 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 + +; zlibwapi v1.2.4 added: + fill_win32_filefunc64 @111 + fill_win32_filefunc64A @112 + fill_win32_filefunc64W @113 + + unzOpen64 @120 + unzOpen2_64 @121 + unzGetGlobalInfo64 @122 + unzGetCurrentFileInfo64 @124 + unzGetCurrentFileZStreamPos64 @125 + unztell64 @126 + unzGetFilePos64 @127 + unzGoToFilePos64 @128 + + zipOpen64 @130 + zipOpen2_64 @131 + zipOpenNewFileInZip64 @132 + zipOpenNewFileInZip2_64 @133 + zipOpenNewFileInZip3_64 @134 + zipOpenNewFileInZip4_64 @135 + zipCloseFileInZipRaw64 @136 + +; zlib1 v1.2.4 added: + adler32_combine @140 + crc32_combine @142 + deflateSetHeader @144 + deflateTune @145 + gzbuffer @146 + gzclose_r @147 + gzclose_w @148 + gzdirect @149 + gzoffset @150 + inflateGetHeader @156 + inflateMark @157 + inflatePrime @158 + inflateReset2 @159 + inflateUndermine @160 + +; zlib1 v1.2.6 added: + gzgetc_ @161 + inflateResetKeep @163 + deflateResetKeep @164 + +; zlib1 v1.2.7 added: + gzopen_w @165 + +; zlib1 v1.2.8 added: + inflateGetDictionary @166 + gzvprintf @167 diff --git a/libz/contrib/vstudio/vc9/zlibvc.sln b/libz/contrib/vstudio/vc9/zlibvc.sln new file mode 100644 index 000000000..b4829671f --- /dev/null +++ b/libz/contrib/vstudio/vc9/zlibvc.sln @@ -0,0 +1,144 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestZlibDll", "testzlibdll.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libz/contrib/vstudio/vc9/zlibvc.vcproj b/libz/contrib/vstudio/vc9/zlibvc.vcproj new file mode 100644 index 000000000..c9a89471e --- /dev/null +++ b/libz/contrib/vstudio/vc9/zlibvc.vcproj @@ -0,0 +1,1156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libz/crc32.c b/libz/crc32.c new file mode 100644 index 000000000..979a7190a --- /dev/null +++ b/libz/crc32.c @@ -0,0 +1,425 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Definitions for doing the crc four data bytes at a time. */ +#if !defined(NOBYFOUR) && defined(Z_U4) +# define BYFOUR +#endif +#ifdef BYFOUR + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local z_crc_t FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const z_crc_t FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + z_crc_t c; + int n, k; + z_crc_t poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0; + for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) + poly |= (z_crc_t)1 << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (z_crc_t)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = ZSWAP32(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = ZSWAP32(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const z_crc_t FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const z_crc_t FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const z_crc_t FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const z_crc_t FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + z_crc_t endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = (z_crc_t)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register z_crc_t c; + register const z_crc_t FAR *buf4; + + c = ZSWAP32((z_crc_t)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(ZSWAP32(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/libz/crc32.h b/libz/crc32.h new file mode 100644 index 000000000..9e0c77810 --- /dev/null +++ b/libz/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const z_crc_t FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/libz/deflate.c b/libz/deflate.c new file mode 100644 index 000000000..696957705 --- /dev/null +++ b/libz/deflate.c @@ -0,0 +1,1967 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + z_const unsigned char *next; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (MIN_MATCH-1); + do { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH-1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateResetKeep (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + int ret; + + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePending (strm, pending, bits) + unsigned *pending; + int *bits; + z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + deflate_state *s; + int put; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + if (err == Z_BUF_ERROR && s->pending == 0) + err = Z_OK; + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len; + deflate_state *s = strm->state; + + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) { + s->pending_out = s->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if ((long)s->strstart > s->block_start) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= MAX_MATCH) { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/libz/deflate.h b/libz/deflate.h new file mode 100644 index 000000000..ce0299edd --- /dev/null +++ b/libz/deflate.h @@ -0,0 +1,346 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2012 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define Buf_size 16 +/* size of bit buffer in bi_buf */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* can only be DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/libz/gzclose.c b/libz/gzclose.c new file mode 100644 index 000000000..caeb99a31 --- /dev/null +++ b/libz/gzclose.c @@ -0,0 +1,25 @@ +/* gzclose.c -- zlib gzclose() function + * Copyright (C) 2004, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* gzclose() is in a separate file so that it is linked in only if it is used. + That way the other gzclose functions can be used instead to avoid linking in + unneeded compression or decompression routines. */ +int ZEXPORT gzclose(file) + gzFile file; +{ +#ifndef NO_GZCOMPRESS + gz_statep state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); +#else + return gzclose_r(file); +#endif +} diff --git a/libz/gzguts.h b/libz/gzguts.h new file mode 100644 index 000000000..d87659d03 --- /dev/null +++ b/libz/gzguts.h @@ -0,0 +1,209 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include +#include "zlib.h" +#ifdef STDC +# include +# include +# include +#endif +#include + +#ifdef _WIN32 +# include +#endif + +#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) +# include +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif + +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS +/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +# ifdef VMS +# define NO_vsnprintf +# endif +# ifdef __OS400__ +# define NO_vsnprintf +# endif +# ifdef __MVS__ +# define NO_vsnprintf +# endif +#endif + +/* unlike snprintf (which is required in C99, yet still not supported by + Microsoft more than a decade later!), _snprintf does not guarantee null + termination of the result -- however this is only used in gzlib.c where + the result is assured to fit in the space provided */ +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +/* gz* functions always use library allocation functions */ +#ifndef STDC + extern voidp malloc OF((uInt size)); + extern void free OF((voidpf ptr)); +#endif + +/* get errno and strerror definition */ +#if defined UNDER_CE +# include +# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#else +# ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +# else +# define zstrerror() "stdio error (consult errno)" +# endif +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#define GZBUFSIZE 8192 + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state FAR *gz_statep; + +/* shared functions */ +void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +#if defined UNDER_CE +char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +#endif + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#ifdef INT_MAX +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#else +unsigned ZLIB_INTERNAL gz_intmax OF((void)); +# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#endif diff --git a/libz/gzlib.c b/libz/gzlib.c new file mode 100644 index 000000000..fae202ef8 --- /dev/null +++ b/libz/gzlib.c @@ -0,0 +1,634 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +#if defined(_WIN32) && !defined(__BORLANDC__) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +local void gz_reset OF((gz_statep)); +local gzFile gz_open OF((const void *, int, const char *)); + +#if defined UNDER_CE + +/* Map the Windows error number in ERROR to a locale-dependent error message + string and return a pointer to it. Typically, the values for ERROR come + from GetLastError. + + The string pointed to shall not be modified by the application, but may be + overwritten by a subsequent call to gz_strwinerror + + The gz_strwinerror function does not change the current setting of + GetLastError. */ +char ZLIB_INTERNAL *gz_strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +#endif /* UNDER_CE */ + +/* Reset gzip file state */ +local void gz_reset(state) + gz_statep state; +{ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +local gzFile gz_open(path, fd, mode) + const void *path; + int fd; + const char *mode; +{ + gz_statep state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef _WIN32 + if (fd == -2) { + len = wcstombs(NULL, path, 0); + if (len == (size_t)-1) + len = 0; + } + else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + free(state); + return NULL; + } +#ifdef _WIN32 + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else +#endif +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->path, len + 1, "%s", (const char *)path); +#else + strcpy(state->path, path); +#endif + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#ifdef _WIN32 + fd == -2 ? _wopen(path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzopen64(path, mode) + const char *path; + const char *mode; +{ + return gz_open(path, -1, mode); +} + +/* -- see zlib.h -- */ +gzFile ZEXPORT gzdopen(fd, mode) + int fd; + const char *mode; +{ + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ +#else + sprintf(path, "", fd); /* for debugging */ +#endif + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef _WIN32 +gzFile ZEXPORT gzopen_w(path, mode) + const wchar_t *path; + const char *mode; +{ + return gz_open(path, -2, mode); +} +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzbuffer(file, size) + gzFile file; + unsigned size; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzrewind(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzseek64(file, offset, whence) + gzFile file; + z_off64_t offset; + int whence; +{ + unsigned n; + z_off64_t ret; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? + (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzseek(file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + z_off64_t ret; + + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gztell64(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gztell(file) + gzFile file; +{ + z_off64_t ret; + + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +z_off64_t ZEXPORT gzoffset64(file) + gzFile file; +{ + z_off64_t offset; + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +z_off_t ZEXPORT gzoffset(file) + gzFile file; +{ + z_off64_t ret; + + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzeof(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * ZEXPORT gzerror(file, errnum) + gzFile file; + int *errnum; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : + (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void ZEXPORT gzclearerr(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void ZLIB_INTERNAL gz_error(state, err, msg) + gz_statep state; + int err; + const char *msg; +{ + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) { + state->err = Z_MEM_ERROR; + return; + } +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); +#else + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); +#endif + return; +} + +#ifndef INT_MAX +/* portably return maximum value for an int (when limits.h presumed not + available) -- we need to do this to cover cases where 2's complement not + used, since C standard permits 1's complement and sign-bit representations, + otherwise we could just use ((unsigned)-1) >> 1 */ +unsigned ZLIB_INTERNAL gz_intmax() +{ + unsigned p, q; + + p = 1; + do { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; +} +#endif diff --git a/libz/gzread.c b/libz/gzread.c new file mode 100644 index 000000000..bf4538eb2 --- /dev/null +++ b/libz/gzread.c @@ -0,0 +1,594 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); +local int gz_avail OF((gz_statep)); +local int gz_look OF((gz_statep)); +local int gz_decomp OF((gz_statep)); +local int gz_fetch OF((gz_statep)); +local int gz_skip OF((gz_statep, z_off64_t)); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +local int gz_load(state, buf, len, have) + gz_statep state; + unsigned char *buf; + unsigned len; + unsigned *have; +{ + int ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +local int gz_avail(state) + gz_statep state; +{ + unsigned got; + z_streamp strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +local int gz_look(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + if (strm->avail_in) { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +local int gz_decomp(state) + gz_statep state; +{ + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +local int gz_fetch(state) + gz_statep state; +{ + z_streamp strm = &(state->strm); + + do { + switch(state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +local int gz_skip(state, len) + gz_statep state; + z_off64_t len; +{ + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; + + /* need more data to skip -- load up output buffer */ + else { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzread(file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + unsigned got, n; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return -1; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* first just try copying data from the output buffer */ + if (state->x.have) { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || len < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, len, &n) == -1) + return -1; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return -1; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; +} + +/* -- see zlib.h -- */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(file) + gzFile file; +{ + int ret; + unsigned char buf[1]; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; +} + +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzdirect(file) + gzFile file; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_r(file) + gzFile file; +{ + int ret, err; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; +} diff --git a/libz/gzwrite.c b/libz/gzwrite.c new file mode 100644 index 000000000..aa767fbf6 --- /dev/null +++ b/libz/gzwrite.c @@ -0,0 +1,577 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "gzguts.h" + +/* Local functions */ +local int gz_init OF((gz_statep)); +local int gz_comp OF((gz_statep, int)); +local int gz_zero OF((gz_statep, z_off64_t)); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on failure or 0 on success. */ +local int gz_init(state) + gz_statep state; +{ + int ret; + z_streamp strm = &(state->strm); + + /* allocate input buffer */ + state->in = (unsigned char *)malloc(state->want); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file, otherwise 0. + flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, + then the deflate() state is reset to start a new gzip stream. If gz->direct + is true, then simply write to the output file without compressing, and + ignore flush. */ +local int gz_comp(state, flush) + gz_statep state; + int flush; +{ + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); + + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on error, 0 on success. */ +local int gz_zero(state, len) + gz_statep state; + z_off64_t len; +{ + int first; + unsigned n; + z_streamp strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? + (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzwrite(file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + unsigned put = len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids the flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + copy = state->size - have; + if (copy > len) + copy = len; + memcpy(state->in + have, buf, copy); + strm->avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (z_const Bytef *)buf; + state->x.pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } + + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzputs(file, str) + gzFile file; + const char *str; +{ + int ret; + unsigned len; + + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; +} + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#include + +/* -- see zlib.h -- */ +int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf((char *)(state->in), format, va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = vsprintf((char *)(state->in), format, va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf((char *)(state->in), size, format, va); + len = strlen((char *)(state->in)); +# else + len = vsnprintf((char *)(state->in), size, format, va); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) +{ + va_list va; + int ret; + + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; +} + +#else /* !STDC && !Z_HAVE_STDARG_H */ + +/* -- see zlib.h -- */ +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + int size, len; + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; +# else + len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen((char *)(state->in)); +# else + len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, + a19, a20); +# endif +#endif + + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; + + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; +} + +#endif + +/* -- see zlib.h -- */ +int ZEXPORT gzflush(file, flush) + gzFile file; + int flush; +{ + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzsetparams(file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_statep state; + z_streamp strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int ZEXPORT gzclose_w(file) + gzFile file; +{ + int ret = Z_OK; + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; +} diff --git a/libz/infback.c b/libz/infback.c new file mode 100644 index 000000000..f3833c2e4 --- /dev/null +++ b/libz/infback.c @@ -0,0 +1,640 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_streamp strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_streamp strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; + + /* process literal */ + if (here.op == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_streamp strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/libz/inffast.c b/libz/inffast.c new file mode 100644 index 000000000..bda59ceb6 --- /dev/null +++ b/libz/inffast.c @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010, 2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/libz/inffast.h b/libz/inffast.h new file mode 100644 index 000000000..e5c1aa4ca --- /dev/null +++ b/libz/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/libz/inffixed.h b/libz/inffixed.h new file mode 100644 index 000000000..d62832776 --- /dev/null +++ b/libz/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. + It is part of the implementation of this library and is + subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/libz/inflate.c b/libz/inflate.c new file mode 100644 index 000000000..870f89bb4 --- /dev/null +++ b/libz/inflate.c @@ -0,0 +1,1512 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2012 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, + unsigned copy)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateResetKeep(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, end, copy) +z_streamp strm; +const Bytef *end; +unsigned copy; +{ + struct inflate_state FAR *state; + unsigned dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) { + zmemcpy(state->window, end - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, end - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, end - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (const code FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) +z_streamp strm; +Bytef *dictionary; +uInt *dictLength; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long dictid; + int ret; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +const unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/libz/inflate.h b/libz/inflate.h new file mode 100644 index 000000000..95f4986d4 --- /dev/null +++ b/libz/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/libz/inftrees.c b/libz/inftrees.c new file mode 100644 index 000000000..44d89cf24 --- /dev/null +++ b/libz/inftrees.c @@ -0,0 +1,306 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2013 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff != 0) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/libz/inftrees.h b/libz/inftrees.h new file mode 100644 index 000000000..baa53a0b1 --- /dev/null +++ b/libz/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/libz/libzv.h b/libz/libzv.h new file mode 100644 index 000000000..3f528ea1e --- /dev/null +++ b/libz/libzv.h @@ -0,0 +1 @@ +#define LIBZ_VERSION_TEXT "Libz 1.2.8" diff --git a/libz/make_vms.com b/libz/make_vms.com new file mode 100644 index 000000000..65e9d0cbc --- /dev/null +++ b/libz/make_vms.com @@ -0,0 +1,867 @@ +$! make libz under VMS written by +$! Martin P.J. Zinser +$! +$! In case of problems with the install you might contact me at +$! zinser@zinser.no-ip.info(preferred) or +$! martin.zinser@eurexchange.com (work) +$! +$! Make procedure history for Zlib +$! +$!------------------------------------------------------------------------------ +$! Version history +$! 0.01 20060120 First version to receive a number +$! 0.02 20061008 Adapt to new Makefile.in +$! 0.03 20091224 Add support for large file check +$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite +$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in +$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples +$! subdir path, update module search in makefile.in +$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned +$! shared image creation +$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared +$! image +$! 0.09 20120305 SMS. P1 sets builder ("MMK", "MMS", " " (built-in)). +$! "" -> automatic, preference: MMK, MMS, built-in. +$! +$ on error then goto err_exit +$! +$ true = 1 +$ false = 0 +$ tmpnam = "temp_" + f$getjpi("","pid") +$ tt = tmpnam + ".txt" +$ tc = tmpnam + ".c" +$ th = tmpnam + ".h" +$ define/nolog tconfig 'th' +$ its_decc = false +$ its_vaxc = false +$ its_gnuc = false +$ s_case = False +$! +$! Setup variables holding "config" information +$! +$ Make = "''p1'" +$ name = "Zlib" +$ version = "?.?.?" +$ v_string = "ZLIB_VERSION" +$ v_file = "zlib.h" +$ ccopt = "/include = []" +$ lopts = "" +$ dnsrl = "" +$ aconf_in_file = "zconf.h.in#zconf.h_in#zconf_h.in" +$ conf_check_string = "" +$ linkonly = false +$ optfile = name + ".opt" +$ mapfile = name + ".map" +$ libdefs = "" +$ vax = f$getsyi("HW_MODEL").lt.1024 +$ axp = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096 +$ ia64 = f$getsyi("HW_MODEL").ge.4096 +$! +$! 2012-03-05 SMS. +$! Why is this needed? And if it is needed, why not simply ".not. vax"? +$! +$!!! if axp .or. ia64 then set proc/parse=extended +$! +$ whoami = f$parse(f$environment("Procedure"),,,,"NO_CONCEAL") +$ mydef = F$parse(whoami,,,"DEVICE") +$ mydir = f$parse(whoami,,,"DIRECTORY") - "][" +$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type") +$! +$! Check for MMK/MMS +$! +$ if (Make .eqs. "") +$ then +$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS" +$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK" +$ else +$ Make = f$edit( Make, "trim") +$ endif +$! +$ gosub find_version +$! +$ open/write topt tmp.opt +$ open/write optf 'optfile' +$! +$ gosub check_opts +$! +$! Look for the compiler used +$! +$ gosub check_compiler +$ close topt +$ close optf +$! +$ if its_decc +$ then +$ ccopt = "/prefix=all" + ccopt +$ if f$trnlnm("SYS") .eqs. "" +$ then +$ if axp +$ then +$ define sys sys$library: +$ else +$ ccopt = "/decc" + ccopt +$ define sys decc$library_include: +$ endif +$ endif +$! +$! 2012-03-05 SMS. +$! Why /NAMES = AS_IS? Why not simply ".not. vax"? And why not on VAX? +$! +$ if axp .or. ia64 +$ then +$ ccopt = ccopt + "/name=as_is/opt=(inline=speed)" +$ s_case = true +$ endif +$ endif +$ if its_vaxc .or. its_gnuc +$ then +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ endif +$! +$! Build a fake configure input header +$! +$ open/write conf_hin config.hin +$ write conf_hin "#undef _LARGEFILE64_SOURCE" +$ close conf_hin +$! +$! +$ i = 0 +$FIND_ACONF: +$ fname = f$element(i,"#",aconf_in_file) +$ if fname .eqs. "#" then goto AMISS_ERR +$ if f$search(fname) .eqs. "" +$ then +$ i = i + 1 +$ goto find_aconf +$ endif +$ open/read/err=aconf_err aconf_in 'fname' +$ open/write aconf zconf.h +$ACONF_LOOP: +$ read/end_of_file=aconf_exit aconf_in line +$ work = f$edit(line, "compress,trim") +$ if f$extract(0,6,work) .nes. "#undef" +$ then +$ if f$extract(0,12,work) .nes. "#cmakedefine" +$ then +$ write aconf line +$ endif +$ else +$ cdef = f$element(1," ",work) +$ gosub check_config +$ endif +$ goto aconf_loop +$ACONF_EXIT: +$ write aconf "" +$ write aconf "/* VMS specifics added by make_vms.com: */" +$ write aconf "#define VMS 1" +$ write aconf "#include " +$ write aconf "#include " +$ write aconf "#ifdef _LARGEFILE" +$ write aconf "# define off64_t __off64_t" +$ write aconf "# define fopen64 fopen" +$ write aconf "# define fseeko64 fseeko" +$ write aconf "# define lseek64 lseek" +$ write aconf "# define ftello64 ftell" +$ write aconf "#endif" +$ write aconf "#if !defined( __VAX) && (__CRTL_VER >= 70312000)" +$ write aconf "# define HAVE_VSNPRINTF" +$ write aconf "#endif" +$ close aconf_in +$ close aconf +$ if f$search("''th'") .nes. "" then delete 'th';* +$! Build the thing plain or with mms +$! +$ write sys$output "Compiling Zlib sources ..." +$ if make.eqs."" +$ then +$ if (f$search( "example.obj;*") .nes. "") then delete example.obj;* +$ if (f$search( "minigzip.obj;*") .nes. "") then delete minigzip.obj;* +$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - + adler32.c zlib.h zconf.h +$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - + compress.c zlib.h zconf.h +$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - + crc32.c zlib.h zconf.h +$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - + deflate.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" - + gzclose.c zutil.h zlib.h zconf.h +$ CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" - + gzlib.c zutil.h zlib.h zconf.h +$ CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" - + gzread.c zutil.h zlib.h zconf.h +$ CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" - + gzwrite.c zutil.h zlib.h zconf.h +$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" - + infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h +$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - + inffast.c zutil.h zlib.h zconf.h inffast.h +$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - + inflate.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - + inftrees.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - + trees.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - + uncompr.c zlib.h zconf.h +$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - + zutil.c zutil.h zlib.h zconf.h +$ write sys$output "Building Zlib ..." +$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ +$ write sys$output "Building example..." +$ CALL MAKE example.OBJ "CC ''CCOPT' [.test]example" - + [.test]example.c zlib.h zconf.h +$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb +$ write sys$output "Building minigzip..." +$ CALL MAKE minigzip.OBJ "CC ''CCOPT' [.test]minigzip" - + [.test]minigzip.c zlib.h zconf.h +$ call make minigzip.exe - + "LINK minigzip,libz.olb/lib" - + minigzip.obj libz.olb +$ else +$ gosub crea_mms +$ write sys$output "Make ''name' ''version' with ''Make' " +$ 'make' +$ endif +$! +$! Create shareable image +$! +$ gosub crea_olist +$ write sys$output "Creating libzshr.exe" +$ call map_2_shopt 'mapfile' 'optfile' +$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt +$ write sys$output "Zlib build completed" +$ delete/nolog tmp.opt;* +$ exit +$AMISS_ERR: +$ write sys$output "No source for config.hin found." +$ write sys$output "Tried any of ''aconf_in_file'" +$ goto err_exit +$CC_ERR: +$ write sys$output "C compiler required to build ''name'" +$ goto err_exit +$ERR_EXIT: +$ set message/facil/ident/sever/text +$ close/nolog optf +$ close/nolog topt +$ close/nolog aconf_in +$ close/nolog aconf +$ close/nolog out +$ close/nolog min +$ close/nolog mod +$ close/nolog h_in +$ write sys$output "Exiting..." +$ exit 2 +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE +$!------------------------------------------------------------------------------ +$! +$! Check command line options and set symbols accordingly +$! +$!------------------------------------------------------------------------------ +$! Version history +$! 0.01 20041206 First version to receive a number +$! 0.02 20060126 Add new "HELP" target +$ CHECK_OPTS: +$ i = 1 +$ OPT_LOOP: +$ if i .lt. 9 +$ then +$ cparm = f$edit(p'i',"upcase") +$! +$! Check if parameter actually contains something +$! +$ if f$edit(cparm,"trim") .nes. "" +$ then +$ if cparm .eqs. "DEBUG" +$ then +$ ccopt = ccopt + "/noopt/deb" +$ lopts = lopts + "/deb" +$ endif +$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ ccopt = ccopt + f$extract(start,len,cparm) +$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) - + then s_case = true +$ endif +$ if cparm .eqs. "LINK" then linkonly = true +$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ lopts = lopts + f$extract(start,len,cparm) +$ endif +$ if f$locate("CC=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ cc_com = f$extract(start,len,cparm) + if (cc_com .nes. "DECC") .and. - + (cc_com .nes. "VAXC") .and. - + (cc_com .nes. "GNUC") +$ then +$ write sys$output "Unsupported compiler choice ''cc_com' ignored" +$ write sys$output "Use DECC, VAXC, or GNUC instead" +$ else +$ if cc_com .eqs. "DECC" then its_decc = true +$ if cc_com .eqs. "VAXC" then its_vaxc = true +$ if cc_com .eqs. "GNUC" then its_gnuc = true +$ endif +$ endif +$ if f$locate("MAKE=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ mmks = f$extract(start,len,cparm) +$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS") +$ then +$ make = mmks +$ else +$ write sys$output "Unsupported make choice ''mmks' ignored" +$ write sys$output "Use MMK or MMS instead" +$ endif +$ endif +$ if cparm .eqs. "HELP" then gosub bhelp +$ endif +$ i = i + 1 +$ goto opt_loop +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Look for the compiler used +$! +$! Version history +$! 0.01 20040223 First version to receive a number +$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists +$! 0.03 20060202 Extend handling of GNU C +$! 0.04 20090402 Compaq -> hp +$CHECK_COMPILER: +$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) +$ then +$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "") +$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "") +$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "") +$ endif +$! +$! Exit if no compiler available +$! +$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) +$ then goto CC_ERR +$ else +$ if its_decc +$ then +$ write sys$output "CC compiler check ... hp C" +$ if f$trnlnm("decc$no_rooted_search_lists") .nes. "" +$ then +$ dnrsl = f$trnlnm("decc$no_rooted_search_lists") +$ endif +$ define/nolog decc$no_rooted_search_lists 1 +$ else +$ if its_vaxc then write sys$output "CC compiler check ... VAX C" +$ if its_gnuc +$ then +$ write sys$output "CC compiler check ... GNU C" +$ if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib" +$ if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib" +$ cc = "gcc" +$ endif +$ if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share" +$ if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share" +$ endif +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! If MMS/MMK are available dump out the descrip.mms if required +$! +$CREA_MMS: +$ write sys$output "Creating descrip.mms..." +$ create descrip.mms +$ open/append out descrip.mms +$ copy sys$input: out +$ deck +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser +# + +OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\ + gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, \ + inftrees.obj, inffast.obj + +$ eod +$ write out "CFLAGS=", ccopt +$ write out "LOPTS=", lopts +$ write out "all : example.exe minigzip.exe libz.olb" +$ copy sys$input: out +$ deck + @ write sys$output " Example applications available" + +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link $(LOPTS) example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link $(LOPTS) minigzip,libz.olb/lib + +clean : + delete *.obj;*,libz.olb;*,*.opt;*,*.exe;* + + +# Other dependencies. +adler32.obj : adler32.c zutil.h zlib.h zconf.h +compress.obj : compress.c zlib.h zconf.h +crc32.obj : crc32.c zutil.h zlib.h zconf.h +deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h +example.obj : [.test]example.c zlib.h zconf.h +gzclose.obj : gzclose.c zutil.h zlib.h zconf.h +gzlib.obj : gzlib.c zutil.h zlib.h zconf.h +gzread.obj : gzread.c zutil.h zlib.h zconf.h +gzwrite.obj : gzwrite.c zutil.h zlib.h zconf.h +inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h +inflate.obj : inflate.c zutil.h zlib.h zconf.h +inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h +minigzip.obj : [.test]minigzip.c zlib.h zconf.h +trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h +uncompr.obj : uncompr.c zlib.h zconf.h +zutil.obj : zutil.c zutil.h zlib.h zconf.h +infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h +$ eod +$ close out +$ return +$!------------------------------------------------------------------------------ +$! +$! Read list of core library sources from makefile.in and create options +$! needed to build shareable image +$! +$CREA_OLIST: +$ open/read min makefile.in +$ open/write mod modules.opt +$ src_check_list = "OBJZ =#OBJG =" +$MRLOOP: +$ read/end=mrdone min rec +$ i = 0 +$SRC_CHECK_LOOP: +$ src_check = f$element(i, "#", src_check_list) +$ i = i+1 +$ if src_check .eqs. "#" then goto mrloop +$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop +$ rec = rec - src_check +$ gosub extra_filnam +$ if (f$element(1,"\",rec) .eqs. "\") then goto mrloop +$MRSLOOP: +$ read/end=mrdone min rec +$ gosub extra_filnam +$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop +$MRDONE: +$ close min +$ close mod +$ return +$!------------------------------------------------------------------------------ +$! +$! Take record extracted in crea_olist and split it into single filenames +$! +$EXTRA_FILNAM: +$ myrec = f$edit(rec - "\", "trim,compress") +$ i = 0 +$FELOOP: +$ srcfil = f$element(i," ", myrec) +$ if (srcfil .nes. " ") +$ then +$ write mod f$parse(srcfil,,,"NAME"), ".obj" +$ i = i + 1 +$ goto feloop +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Find current Zlib version number +$! +$FIND_VERSION: +$ open/read h_in 'v_file' +$hloop: +$ read/end=hdone h_in rec +$ rec = f$edit(rec,"TRIM") +$ if (f$extract(0,1,rec) .nes. "#") then goto hloop +$ rec = f$edit(rec - "#", "TRIM") +$ if f$element(0," ",rec) .nes. "define" then goto hloop +$ if f$element(1," ",rec) .eqs. v_string +$ then +$ version = 'f$element(2," ",rec)' +$ goto hdone +$ endif +$ goto hloop +$hdone: +$ close h_in +$ return +$!------------------------------------------------------------------------------ +$! +$CHECK_CONFIG: +$! +$ in_ldef = f$locate(cdef,libdefs) +$ if (in_ldef .lt. f$length(libdefs)) +$ then +$ write aconf "#define ''cdef' 1" +$ libdefs = f$extract(0,in_ldef,libdefs) + - + f$extract(in_ldef + f$length(cdef) + 1, - + f$length(libdefs) - in_ldef - f$length(cdef) - 1, - + libdefs) +$ else +$ if (f$type('cdef') .eqs. "INTEGER") +$ then +$ write aconf "#define ''cdef' ", 'cdef' +$ else +$ if (f$type('cdef') .eqs. "STRING") +$ then +$ write aconf "#define ''cdef' ", """", '''cdef'', """" +$ else +$ gosub check_cc_def +$ endif +$ endif +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Check if this is a define relating to the properties of the C/C++ +$! compiler +$! +$ CHECK_CC_DEF: +$ if (cdef .eqs. "_LARGEFILE64_SOURCE") +$ then +$ copy sys$input: 'tc' +$ deck +#include "tconfig" +#define _LARGEFILE +#include + +int main(){ +FILE *fp; + fp = fopen("temp.txt","r"); + fseeko(fp,1,SEEK_SET); + fclose(fp); +} + +$ eod +$ test_inv = false +$ comm_h = false +$ gosub cc_prop_check +$ return +$ endif +$ write aconf "/* ", line, " */" +$ return +$!------------------------------------------------------------------------------ +$! +$! Check for properties of C/C++ compiler +$! +$! Version history +$! 0.01 20031020 First version to receive a number +$! 0.02 20031022 Added logic for defines with value +$! 0.03 20040309 Make sure local config file gets not deleted +$! 0.04 20041230 Also write include for configure run +$! 0.05 20050103 Add processing of "comment defines" +$CC_PROP_CHECK: +$ cc_prop = true +$ is_need = false +$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true) +$ if f$search(th) .eqs. "" then create 'th' +$ set message/nofac/noident/nosever/notext +$ on error then continue +$ cc 'tmpnam' +$ if .not. ($status) then cc_prop = false +$ on error then continue +$! The headers might lie about the capabilities of the RTL +$ link 'tmpnam',tmp.opt/opt +$ if .not. ($status) then cc_prop = false +$ set message/fac/ident/sever/text +$ on error then goto err_exit +$ delete/nolog 'tmpnam'.*;*/exclude='th' +$ if (cc_prop .and. .not. is_need) .or. - + (.not. cc_prop .and. is_need) +$ then +$ write sys$output "Checking for ''cdef'... yes" +$ if f$type('cdef_val'_yes) .nes. "" +$ then +$ if f$type('cdef_val'_yes) .eqs. "INTEGER" - + then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes) +$ if f$type('cdef_val'_yes) .eqs. "STRING" - + then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes) +$ else +$ call write_config f$fao("#define !AS 1",cdef) +$ endif +$ if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. - + (cdef .eqs. "_LARGEFILE64_SOURCE") then - + call write_config f$string("#define _LARGEFILE 1") +$ else +$ write sys$output "Checking for ''cdef'... no" +$ if (comm_h) +$ then + call write_config f$fao("/* !AS */",line) +$ else +$ if f$type('cdef_val'_no) .nes. "" +$ then +$ if f$type('cdef_val'_no) .eqs. "INTEGER" - + then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no) +$ if f$type('cdef_val'_no) .eqs. "STRING" - + then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no) +$ else +$ call write_config f$fao("#undef !AS",cdef) +$ endif +$ endif +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Check for properties of C/C++ compiler with multiple result values +$! +$! Version history +$! 0.01 20040127 First version +$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05 +$CC_MPROP_CHECK: +$ cc_prop = true +$ i = 1 +$ idel = 1 +$ MT_LOOP: +$ if f$type(result_'i') .eqs. "STRING" +$ then +$ set message/nofac/noident/nosever/notext +$ on error then continue +$ cc 'tmpnam'_'i' +$ if .not. ($status) then cc_prop = false +$ on error then continue +$! The headers might lie about the capabilities of the RTL +$ link 'tmpnam'_'i',tmp.opt/opt +$ if .not. ($status) then cc_prop = false +$ set message/fac/ident/sever/text +$ on error then goto err_exit +$ delete/nolog 'tmpnam'_'i'.*;* +$ if (cc_prop) +$ then +$ write sys$output "Checking for ''cdef'... ", mdef_'i' +$ if f$type(mdef_'i') .eqs. "INTEGER" - + then call write_config f$fao("#define !AS !UL",cdef,mdef_'i') +$ if f$type('cdef_val'_yes) .eqs. "STRING" - + then call write_config f$fao("#define !AS !AS",cdef,mdef_'i') +$ goto msym_clean +$ else +$ i = i + 1 +$ goto mt_loop +$ endif +$ endif +$ write sys$output "Checking for ''cdef'... no" +$ call write_config f$fao("#undef !AS",cdef) +$ MSYM_CLEAN: +$ if (idel .le. msym_max) +$ then +$ delete/sym mdef_'idel' +$ idel = idel + 1 +$ goto msym_clean +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Write configuration to both permanent and temporary config file +$! +$! Version history +$! 0.01 20031029 First version to receive a number +$! +$WRITE_CONFIG: SUBROUTINE +$ write aconf 'p1' +$ open/append confh 'th' +$ write confh 'p1' +$ close confh +$ENDSUBROUTINE +$!------------------------------------------------------------------------------ +$! +$! Analyze the project map file and create the symbol vector for a shareable +$! image from it +$! +$! Version history +$! 0.01 20120128 First version +$! 0.02 20120226 Add pre-load logic +$! +$ MAP_2_SHOPT: Subroutine +$! +$ SAY := "WRITE_ SYS$OUTPUT" +$! +$ IF F$SEARCH("''P1'") .EQS. "" +$ THEN +$ SAY "MAP_2_SHOPT-E-NOSUCHFILE: Error, inputfile ''p1' not available" +$ goto exit_m2s +$ ENDIF +$ IF "''P2'" .EQS. "" +$ THEN +$ SAY "MAP_2_SHOPT: Error, no output file provided" +$ goto exit_m2s +$ ENDIF +$! +$ module1 = "deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary" +$ module2 = "gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread" +$ module3 = "gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary" +$ module4 = "inflateSync#uncompress#zlibVersion#compress" +$ open/read map 'p1 +$ if axp .or. ia64 +$ then +$ open/write aopt a.opt +$ open/write bopt b.opt +$ write aopt " CASE_SENSITIVE=YES" +$ write bopt "SYMBOL_VECTOR= (-" +$ mod_sym_num = 1 +$ MOD_SYM_LOOP: +$ if f$type(module'mod_sym_num') .nes. "" +$ then +$ mod_in = 0 +$ MOD_SYM_IN: +$ shared_proc = f$element(mod_in, "#", module'mod_sym_num') +$ if shared_proc .nes. "#" +$ then +$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",- + f$edit(shared_proc,"upcase"),shared_proc) +$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc) +$ mod_in = mod_in + 1 +$ goto mod_sym_in +$ endif +$ mod_sym_num = mod_sym_num + 1 +$ goto mod_sym_loop +$ endif +$MAP_LOOP: +$ read/end=map_end map line +$ if (f$locate("{",line).lt. f$length(line)) .or. - + (f$locate("global:", line) .lt. f$length(line)) +$ then +$ proc = true +$ goto map_loop +$ endif +$ if f$locate("}",line).lt. f$length(line) then proc = false +$ if f$locate("local:", line) .lt. f$length(line) then proc = false +$ if proc +$ then +$ shared_proc = f$edit(line,"collapse") +$ chop_semi = f$locate(";", shared_proc) +$ if chop_semi .lt. f$length(shared_proc) then - + shared_proc = f$extract(0, chop_semi, shared_proc) +$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",- + f$edit(shared_proc,"upcase"),shared_proc) +$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc) +$ endif +$ goto map_loop +$MAP_END: +$ close/nolog aopt +$ close/nolog bopt +$ open/append libopt 'p2' +$ open/read aopt a.opt +$ open/read bopt b.opt +$ALOOP: +$ read/end=aloop_end aopt line +$ write libopt line +$ goto aloop +$ALOOP_END: +$ close/nolog aopt +$ sv = "" +$BLOOP: +$ read/end=bloop_end bopt svn +$ if (svn.nes."") +$ then +$ if (sv.nes."") then write libopt sv +$ sv = svn +$ endif +$ goto bloop +$BLOOP_END: +$ write libopt f$extract(0,f$length(sv)-2,sv), "-" +$ write libopt ")" +$ close/nolog bopt +$ delete/nolog/noconf a.opt;*,b.opt;* +$ else +$ if vax +$ then +$ open/append libopt 'p2' +$ mod_sym_num = 1 +$ VMOD_SYM_LOOP: +$ if f$type(module'mod_sym_num') .nes. "" +$ then +$ mod_in = 0 +$ VMOD_SYM_IN: +$ shared_proc = f$element(mod_in, "#", module'mod_sym_num') +$ if shared_proc .nes. "#" +$ then +$ write libopt f$fao("UNIVERSAL=!AS",- + f$edit(shared_proc,"upcase")) +$ mod_in = mod_in + 1 +$ goto vmod_sym_in +$ endif +$ mod_sym_num = mod_sym_num + 1 +$ goto vmod_sym_loop +$ endif +$VMAP_LOOP: +$ read/end=vmap_end map line +$ if (f$locate("{",line).lt. f$length(line)) .or. - + (f$locate("global:", line) .lt. f$length(line)) +$ then +$ proc = true +$ goto vmap_loop +$ endif +$ if f$locate("}",line).lt. f$length(line) then proc = false +$ if f$locate("local:", line) .lt. f$length(line) then proc = false +$ if proc +$ then +$ shared_proc = f$edit(line,"collapse") +$ chop_semi = f$locate(";", shared_proc) +$ if chop_semi .lt. f$length(shared_proc) then - + shared_proc = f$extract(0, chop_semi, shared_proc) +$ write libopt f$fao("UNIVERSAL=!AS",- + f$edit(shared_proc,"upcase")) +$ endif +$ goto vmap_loop +$VMAP_END: +$ else +$ write sys$output "Unknown Architecture (Not VAX, AXP, or IA64)" +$ write sys$output "No options file created" +$ endif +$ endif +$ EXIT_M2S: +$ close/nolog map +$ close/nolog libopt +$ endsubroutine diff --git a/libz/msdos/Makefile.bor b/libz/msdos/Makefile.bor new file mode 100644 index 000000000..3d12a2c25 --- /dev/null +++ b/libz/msdos/Makefile.bor @@ -0,0 +1,115 @@ +# Makefile for zlib +# Borland C++ +# Last updated: 15-Mar-2003 + +# To use, do "make -fmakefile.bor" +# To compile in small model, set below: MODEL=s + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------ Turbo C++, Borland C++ ------------ + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# memory model: one of s, m, c, l (small, medium, compact, large) +MODEL=l + +# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version +CC=bcc +LD=bcc +AR=tlib + +# compiler flags +# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0 +CFLAGS=-O2 -Z -m$(MODEL) $(LOC) + +LDFLAGS=-m$(MODEL) -f- + + +# variables +ZLIB_LIB = zlib_$(MODEL).lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + -del *.obj + -del *.lib + -del *.exe + -del zlib_*.bak + -del foo.gz diff --git a/libz/msdos/Makefile.dj2 b/libz/msdos/Makefile.dj2 new file mode 100644 index 000000000..29b03954d --- /dev/null +++ b/libz/msdos/Makefile.dj2 @@ -0,0 +1,104 @@ +# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.dj2; make test -fmakefile.dj2 +# +# To install libz.a, zconf.h and zlib.h in the djgpp directories, type: +# +# make install -fmakefile.dj2 +# +# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as +# in the sample below if the pattern of the DJGPP distribution is to +# be followed. Remember that, while 'es around <=> are ignored in +# makefiles, they are *not* in batch files or in djgpp.env. +# - - - - - +# [make] +# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include +# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib +# BUTT=-m486 +# - - - - - +# Alternately, these variables may be defined below, overriding the values +# in djgpp.env, as +# INCLUDE_PATH=c:\usr\include +# LIBRARY_PATH=c:\usr\lib + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lz +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=libz.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +OBJA = +# to use the asm code: make OBJA=match.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +check: test +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +libz.a: $(OBJS) $(OBJA) + $(AR) $@ $(OBJS) $(OBJA) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + +# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env . + +.PHONY : uninstall clean + +install: $(INCL) $(LIBS) + -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH) + -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH) + $(INSTALL) zlib.h $(INCLUDE_PATH) + $(INSTALL) zconf.h $(INCLUDE_PATH) + $(INSTALL) libz.a $(LIBRARY_PATH) + +uninstall: + $(RM) $(INCLUDE_PATH)\zlib.h + $(RM) $(INCLUDE_PATH)\zconf.h + $(RM) $(LIBRARY_PATH)\libz.a + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) libz.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/libz/msdos/Makefile.emx b/libz/msdos/Makefile.emx new file mode 100644 index 000000000..9c1b57a58 --- /dev/null +++ b/libz/msdos/Makefile.emx @@ -0,0 +1,69 @@ +# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ + uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/libz/msdos/Makefile.msc b/libz/msdos/Makefile.msc new file mode 100644 index 000000000..ae8378615 --- /dev/null +++ b/libz/msdos/Makefile.msc @@ -0,0 +1,112 @@ +# Makefile for zlib +# Microsoft C 5.1 or later +# Last updated: 19-Mar-2003 + +# To use, do "make makefile.msc" +# To compile in small model, set below: MODEL=S + +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to the LOC macro below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Microsoft C 5.1 and later ------------- + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added +# to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Memory model: one of S, M, C, L (small, medium, compact, large) +MODEL=L + +CC=cl +CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC) +#-Ox generates bad code with MSC 5.1 +LIB_CFLAGS=-Zl $(CFLAGS) + +LD=link +LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode +# "/farcall/packcode" are only useful for `large code' memory models +# but should be a "no-op" for small code models. + + +# variables +ZLIB_LIB = zlib_$(MODEL).lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(LIB_CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: test/minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + + +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + if exist $(ZLIB_LIB) del $(ZLIB_LIB) + lib $(ZLIB_LIB) $(OBJ1); + lib $(ZLIB_LIB) $(OBJ2); + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB); + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB); + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + -del *.obj + -del *.lib + -del *.exe + -del *.map + -del zlib_*.bak + -del foo.gz diff --git a/libz/msdos/Makefile.tc b/libz/msdos/Makefile.tc new file mode 100644 index 000000000..5aec82a9d --- /dev/null +++ b/libz/msdos/Makefile.tc @@ -0,0 +1,100 @@ +# Makefile for zlib +# Turbo C 2.01, Turbo C++ 1.01 +# Last updated: 15-Mar-2003 + +# To use, do "make -fmakefile.tc" +# To compile in small model, set below: MODEL=s + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. For example: +# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +# If you wish to reduce the memory requirements (default 256K for big +# objects plus a few K), you can add to CFLAGS below: +# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------ +MODEL=l +CC=tcc +LD=tcc +AR=tlib +# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 +CFLAGS=-O2 -G -Z -m$(MODEL) +LDFLAGS=-m$(MODEL) -f- + + +# variables +ZLIB_LIB = zlib_$(MODEL).lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $*.c + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +clean: + -del *.obj + -del *.lib + -del *.exe + -del zlib_*.bak + -del foo.gz diff --git a/libz/nintendods/README b/libz/nintendods/README new file mode 100644 index 000000000..ba7a37dbe --- /dev/null +++ b/libz/nintendods/README @@ -0,0 +1,5 @@ +This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template. + +Eduardo Costa +January 3, 2009 + diff --git a/libz/old/Makefile.emx b/libz/old/Makefile.emx new file mode 100644 index 000000000..4d6ab0efa --- /dev/null +++ b/libz/old/Makefile.emx @@ -0,0 +1,69 @@ +# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98. +# Copyright (C) 1995-1998 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type: +# +# make -fmakefile.emx; make test -fmakefile.emx +# + +CC=gcc -Zwin32 + +#CFLAGS=-MMD -O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-MMD -g -DDEBUG +CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ + -Wstrict-prototypes -Wmissing-prototypes + +# If cp.exe is available, replace "copy /Y" with "cp -fp" . +CP=copy /Y +# If gnu install.exe is available, replace $(CP) with ginstall. +INSTALL=$(CP) +# The default value of RM is "rm -f." If "rm.exe" is found, comment out: +RM=del +LDLIBS=-L. -lzlib +LD=$(CC) -s -o +LDSHARED=$(CC) + +INCL=zlib.h zconf.h +LIBS=zlib.a + +AR=ar rcs + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ + gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o + +TEST_OBJS = example.o minigzip.o + +all: example.exe minigzip.exe + +test: all + ./example + echo hello world | .\minigzip | .\minigzip -d + +%.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + +zlib.a: $(OBJS) + $(AR) $@ $(OBJS) + +%.exe : %.o $(LIBS) + $(LD) $@ $< $(LDLIBS) + + +.PHONY : clean + +clean: + $(RM) *.d + $(RM) *.o + $(RM) *.exe + $(RM) zlib.a + $(RM) foo.gz + +DEPS := $(wildcard *.d) +ifneq ($(DEPS),) +include $(DEPS) +endif diff --git a/libz/old/Makefile.riscos b/libz/old/Makefile.riscos new file mode 100644 index 000000000..57e29d3fb --- /dev/null +++ b/libz/old/Makefile.riscos @@ -0,0 +1,151 @@ +# Project: zlib_1_03 +# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430 +# test works out-of-the-box, installs `somewhere' on demand + +# Toolflags: +CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah +C++flags = -c -depend !Depend -IC: -throwback +Linkflags = -aif -c++ -o $@ +ObjAsmflags = -throwback -NoCache -depend !Depend +CMHGflags = +LibFileflags = -c -l -o $@ +Squeezeflags = -o $@ + +# change the line below to where _you_ want the library installed. +libdest = lib:zlib + +# Final targets: +@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ + @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ + @.o.uncompr @.o.zutil + LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ + @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ + @.o.trees @.o.uncompr @.o.zutil +test: @.minigzip @.example @.lib + @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV + @echo running tests: hang on. + @/@.minigzip -f -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -f -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -h -1 libc + @/@.minigzip -d libc-gz + @/@.minigzip -9 libc + @/@.minigzip -d libc-gz + @/@.minigzip -1 libc + @/@.minigzip -d libc-gz + @diff @.lib @.libc + @echo that should have reported '@.lib and @.libc identical' if you have diff. + @/@.example @.fred @.fred + @echo that will have given lots of hello!'s. + +@.minigzip: @.o.minigzip @.lib C:o.Stubs + Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs +@.example: @.o.example @.lib C:o.Stubs + Link $(Linkflags) @.o.example @.lib C:o.Stubs + +install: @.lib + cdir $(libdest) + cdir $(libdest).h + @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV + @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV + @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV + @echo okay, installed zlib in $(libdest) + +clean:; remove @.minigzip + remove @.example + remove @.libc + -wipe @.o.* F~r~cV + remove @.fred + +# User-editable dependencies: +.c.o: + cc $(ccflags) -o $@ $< + +# Static dependencies: + +# Dynamic dependencies: +o.example: c.example +o.example: h.zlib +o.example: h.zconf +o.minigzip: c.minigzip +o.minigzip: h.zlib +o.minigzip: h.zconf +o.adler32: c.adler32 +o.adler32: h.zlib +o.adler32: h.zconf +o.compress: c.compress +o.compress: h.zlib +o.compress: h.zconf +o.crc32: c.crc32 +o.crc32: h.zlib +o.crc32: h.zconf +o.deflate: c.deflate +o.deflate: h.deflate +o.deflate: h.zutil +o.deflate: h.zlib +o.deflate: h.zconf +o.gzio: c.gzio +o.gzio: h.zutil +o.gzio: h.zlib +o.gzio: h.zconf +o.infblock: c.infblock +o.infblock: h.zutil +o.infblock: h.zlib +o.infblock: h.zconf +o.infblock: h.infblock +o.infblock: h.inftrees +o.infblock: h.infcodes +o.infblock: h.infutil +o.infcodes: c.infcodes +o.infcodes: h.zutil +o.infcodes: h.zlib +o.infcodes: h.zconf +o.infcodes: h.inftrees +o.infcodes: h.infblock +o.infcodes: h.infcodes +o.infcodes: h.infutil +o.infcodes: h.inffast +o.inffast: c.inffast +o.inffast: h.zutil +o.inffast: h.zlib +o.inffast: h.zconf +o.inffast: h.inftrees +o.inffast: h.infblock +o.inffast: h.infcodes +o.inffast: h.infutil +o.inffast: h.inffast +o.inflate: c.inflate +o.inflate: h.zutil +o.inflate: h.zlib +o.inflate: h.zconf +o.inflate: h.infblock +o.inftrees: c.inftrees +o.inftrees: h.zutil +o.inftrees: h.zlib +o.inftrees: h.zconf +o.inftrees: h.inftrees +o.inftrees: h.inffixed +o.infutil: c.infutil +o.infutil: h.zutil +o.infutil: h.zlib +o.infutil: h.zconf +o.infutil: h.infblock +o.infutil: h.inftrees +o.infutil: h.infcodes +o.infutil: h.infutil +o.trees: c.trees +o.trees: h.deflate +o.trees: h.zutil +o.trees: h.zlib +o.trees: h.zconf +o.trees: h.trees +o.uncompr: c.uncompr +o.uncompr: h.zlib +o.uncompr: h.zconf +o.zutil: c.zutil +o.zutil: h.zutil +o.zutil: h.zlib +o.zutil: h.zconf diff --git a/libz/old/README b/libz/old/README new file mode 100644 index 000000000..800bf0798 --- /dev/null +++ b/libz/old/README @@ -0,0 +1,3 @@ +This directory contains files that have not been updated for zlib 1.2.x + +(Volunteers are encouraged to help clean this up. Thanks.) diff --git a/libz/old/descrip.mms b/libz/old/descrip.mms new file mode 100644 index 000000000..7066da5b5 --- /dev/null +++ b/libz/old/descrip.mms @@ -0,0 +1,48 @@ +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser + +cc_defs = +c_deb = + +.ifdef __DECC__ +pref = /prefix=all +.endif + +OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\ + inftrees.obj, infcodes.obj, infutil.obj, inffast.obj + +CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) + +all : example.exe minigzip.exe + @ write sys$output " Example applications available" +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib + +clean : + delete *.obj;*,libz.olb;* + + +# Other dependencies. +adler32.obj : zutil.h zlib.h zconf.h +compress.obj : zlib.h zconf.h +crc32.obj : zutil.h zlib.h zconf.h +deflate.obj : deflate.h zutil.h zlib.h zconf.h +example.obj : zlib.h zconf.h +gzio.obj : zutil.h zlib.h zconf.h +infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.obj : zutil.h zlib.h zconf.h infblock.h +inftrees.obj : zutil.h zlib.h zconf.h inftrees.h +infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.obj : zlib.h zconf.h +trees.obj : deflate.h zutil.h zlib.h zconf.h +uncompr.obj : zlib.h zconf.h +zutil.obj : zutil.h zlib.h zconf.h diff --git a/libz/old/os2/Makefile.os2 b/libz/old/os2/Makefile.os2 new file mode 100644 index 000000000..a105aaa5b --- /dev/null +++ b/libz/old/os2/Makefile.os2 @@ -0,0 +1,136 @@ +# Makefile for zlib under OS/2 using GCC (PGCC) +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# cp Makefile.os2 .. +# cd .. +# make -f Makefile.os2 test + +# This makefile will build a static library z.lib, a shared library +# z.dll and a import library zdll.lib. You can use either z.lib or +# zdll.lib by specifying either -lz or -lzdll on gcc's command line + +CC=gcc -Zomf -s + +CFLAGS=-O6 -Wall +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DDEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +#################### BUG WARNING: ##################### +## infcodes.c hits a bug in pgcc-1.0, so you have to use either +## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem) +## This bug is reportedly fixed in pgcc >1.0, but this was not tested +CFLAGS+=-fno-force-mem + +LDFLAGS=-s -L. -lzdll -Zcrtdll +LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll + +VER=1.1.0 +ZLIB=z.lib +SHAREDLIB=z.dll +SHAREDLIBIMP=zdll.lib +LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP) + +AR=emxomfar cr +IMPLIB=emximp +RANLIB=echo +TAR=tar +SHELL=bash + +prefix=/usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \ + algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ + nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \ + contrib/asm386/*.asm contrib/asm386/*.c \ + contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \ + contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ + contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 + +all: example.exe minigzip.exe + +test: all + @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + echo hello world | ./minigzip | ./minigzip -d || \ + echo ' *** minigzip test FAILED ***' ; \ + if ./example; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; \ + fi + +$(ZLIB): $(OBJS) + $(AR) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +$(SHAREDLIB): $(OBJS) os2/z.def + $(LDSHARED) -o $@ $^ + +$(SHAREDLIBIMP): os2/z.def + $(IMPLIB) -o $@ $^ + +example.exe: example.o $(LIBS) + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip.exe: minigzip.o $(LIBS) + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +clean: + rm -f *.o *~ example minigzip libz.a libz.so* foo.gz + +distclean: clean + +zip: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + zip -ul9 zlib$$v $(DISTFILES) + mv Makefile~ Makefile + +dist: + mv Makefile Makefile~; cp -p Makefile.in Makefile + rm -f test.c ztest*.c + d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ + rm -f $$d.tar.gz; \ + if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ + files=""; \ + for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ + cd ..; \ + GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ + if test ! -d $$d; then rm -f $$d; fi + mv Makefile~ Makefile + +tags: + etags *.[ch] + +depend: + makedepend -- $(CFLAGS) -- *.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h +infcodes.o: zutil.h zlib.h zconf.h +infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: infblock.h infcodes.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/libz/old/os2/zlib.def b/libz/old/os2/zlib.def new file mode 100644 index 000000000..4c753f1a3 --- /dev/null +++ b/libz/old/os2/zlib.def @@ -0,0 +1,51 @@ +; +; Slightly modified version of ../nt/zlib.dnt :-) +; + +LIBRARY Z +DESCRIPTION "Zlib compression library for OS/2" +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE + +EXPORTS + adler32 + compress + crc32 + deflate + deflateCopy + deflateEnd + deflateInit2_ + deflateInit_ + deflateParams + deflateReset + deflateSetDictionary + gzclose + gzdopen + gzerror + gzflush + gzopen + gzread + gzwrite + inflate + inflateEnd + inflateInit2_ + inflateInit_ + inflateReset + inflateSetDictionary + inflateSync + uncompress + zlibVersion + gzprintf + gzputc + gzgetc + gzseek + gzrewind + gztell + gzeof + gzsetparams + zError + inflateSyncPoint + get_crc_table + compress2 + gzputs + gzgets diff --git a/libz/old/visual-basic.txt b/libz/old/visual-basic.txt new file mode 100644 index 000000000..57efe5812 --- /dev/null +++ b/libz/old/visual-basic.txt @@ -0,0 +1,160 @@ +See below some functions declarations for Visual Basic. + +Frequently Asked Question: + +Q: Each time I use the compress function I get the -5 error (not enough + room in the output buffer). + +A: Make sure that the length of the compressed buffer is passed by + reference ("as any"), not by value ("as long"). Also check that + before the call of compress this length is equal to the total size of + the compressed buffer and not zero. + + +From: "Jon Caruana" +Subject: Re: How to port zlib declares to vb? +Date: Mon, 28 Oct 1996 18:33:03 -0600 + +Got the answer! (I haven't had time to check this but it's what I got, and +looks correct): + +He has the following routines working: + compress + uncompress + gzopen + gzwrite + gzread + gzclose + +Declares follow: (Quoted from Carlos Rios , in Vb4 form) + +#If Win16 Then 'Use Win16 calls. +Declare Function compress Lib "ZLIB.DLL" (ByVal compr As + String, comprLen As Any, ByVal buf As String, ByVal buflen + As Long) As Integer +Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr + As String, uncomprLen As Any, ByVal compr As String, ByVal + lcompr As Long) As Integer +Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As + String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As + Long) As Integer +#Else +Declare Function compress Lib "ZLIB32.DLL" + (ByVal compr As String, comprLen As Any, ByVal buf As + String, ByVal buflen As Long) As Integer +Declare Function uncompress Lib "ZLIB32.DLL" + (ByVal uncompr As String, uncomprLen As Any, ByVal compr As + String, ByVal lcompr As Long) As Long +Declare Function gzopen Lib "ZLIB32.DLL" + (ByVal file As String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzwrite Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzclose Lib "ZLIB32.DLL" + (ByVal file As Long) As Long +#End If + +-Jon Caruana +jon-net@usa.net +Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member + + +Here is another example from Michael that he +says conforms to the VB guidelines, and that solves the problem of not +knowing the uncompressed size by storing it at the end of the file: + +'Calling the functions: +'bracket meaning: [optional] {Range of possible values} +'Call subCompressFile( [, , [level of compression {1..9}]]) +'Call subUncompressFile() + +Option Explicit +Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller' +Private Const SUCCESS As Long = 0 +Private Const strFilExt As String = ".cpr" +Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef +dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long, +ByVal level As Integer) As Long +Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef +dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long) +As Long + +Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal +strargCprFilPth As String, Optional ByVal intLvl As Integer = 9) + Dim strCprPth As String + Dim lngOriSiz As Long + Dim lngCprSiz As Long + Dim bytaryOri() As Byte + Dim bytaryCpr() As Byte + lngOriSiz = FileLen(strargOriFilPth) + ReDim bytaryOri(lngOriSiz - 1) + Open strargOriFilPth For Binary Access Read As #1 + Get #1, , bytaryOri() + Close #1 + strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth) +'Select file path and name + strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) = +strFilExt, "", strFilExt) 'Add file extension if not exists + lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit +more space then original file size + ReDim bytaryCpr(lngCprSiz - 1) + If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) = +SUCCESS Then + lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100 + ReDim Preserve bytaryCpr(lngCprSiz - 1) + Open strCprPth For Binary Access Write As #1 + Put #1, , bytaryCpr() + Put #1, , lngOriSiz 'Add the the original size value to the end +(last 4 bytes) + Close #1 + Else + MsgBox "Compression error" + End If + Erase bytaryCpr + Erase bytaryOri +End Sub + +Public Sub subUncompressFile(ByVal strargFilPth As String) + Dim bytaryCpr() As Byte + Dim bytaryOri() As Byte + Dim lngOriSiz As Long + Dim lngCprSiz As Long + Dim strOriPth As String + lngCprSiz = FileLen(strargFilPth) + ReDim bytaryCpr(lngCprSiz - 1) + Open strargFilPth For Binary Access Read As #1 + Get #1, , bytaryCpr() + Close #1 + 'Read the original file size value: + lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _ + + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _ + + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _ + + bytaryCpr(lngCprSiz - 4) + ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value + ReDim bytaryOri(lngOriSiz - 1) + If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS +Then + strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt)) + Open strOriPth For Binary Access Write As #1 + Put #1, , bytaryOri() + Close #1 + Else + MsgBox "Uncompression error" + End If + Erase bytaryCpr + Erase bytaryOri +End Sub +Public Property Get lngPercentSmaller() As Long + lngPercentSmaller = lngpvtPcnSml +End Property diff --git a/libz/qnx/package.qpg b/libz/qnx/package.qpg new file mode 100644 index 000000000..aebf6e3ac --- /dev/null +++ b/libz/qnx/package.qpg @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Library + + Medium + + 2.0 + + + + zlib + zlib + alain.bonnefoy@icbt.com + Public + public + www.gzip.org/zlib + + + Jean-Loup Gailly,Mark Adler + www.gzip.org/zlib + + zlib@gzip.org + + + A massively spiffy yet delicately unobtrusive compression library. + zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system. + http://www.gzip.org/zlib + + + + + 1.2.8 + Medium + Stable + + + + + + + No License + + + + Software Development/Libraries and Extensions/C Libraries + zlib,compression + qnx6 + qnx6 + None + Developer + + + + + + + + + + + + + + Install + Post + No + Ignore + + No + Optional + + + + + + + + + + + + + InstallOver + zlib + + + + + + + + + + + + + InstallOver + zlib-dev + + + + + + + + + diff --git a/libz/test/example.c b/libz/test/example.c new file mode 100644 index 000000000..138a699bd --- /dev/null +++ b/libz/test/example.c @@ -0,0 +1,601 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995-2006, 2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zlib.h" +#include + +#ifdef STDC +# include +# include +#endif + +#if defined(VMS) || defined(RISCOS) +# define TESTFILE "foo-gz" +#else +# define TESTFILE "foo.gz" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +z_const char hello[] = "hello, hello!"; +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ + +const char dictionary[] = "hello"; +uLong dictId; /* Adler32 value of the dictionary */ + +void test_deflate OF((Byte *compr, uLong comprLen)); +void test_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_deflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_large_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_flush OF((Byte *compr, uLong *comprLen)); +void test_sync OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_dict_deflate OF((Byte *compr, uLong comprLen)); +void test_dict_inflate OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +int main OF((int argc, char *argv[])); + + +#ifdef Z_SOLO + +void *myalloc OF((void *, unsigned, unsigned)); +void myfree OF((void *, void *)); + +void *myalloc(q, n, m) + void *q; + unsigned n, m; +{ + q = Z_NULL; + return calloc(n, m); +} + +void myfree(void *q, void *p) +{ + q = Z_NULL; + free(p); +} + +static alloc_func zalloc = myalloc; +static free_func zfree = myfree; + +#else /* !Z_SOLO */ + +static alloc_func zalloc = (alloc_func)0; +static free_func zfree = (free_func)0; + +void test_compress OF((Byte *compr, uLong comprLen, + Byte *uncompr, uLong uncomprLen)); +void test_gzio OF((const char *fname, + Byte *uncompr, uLong uncomprLen)); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + uLong len = (uLong)strlen(hello)+1; + + err = compress(compr, &comprLen, (const Bytef*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + exit(1); + } else { + printf("uncompress(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(fname, uncompr, uncomprLen) + const char *fname; /* compressed file name */ + Byte *uncompr; + uLong uncomprLen; +{ +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); +#else + int err; + int len = (int)strlen(hello)+1; + gzFile file; + z_off_t pos; + + file = gzopen(fname, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + gzputc(file, 'h'); + if (gzputs(file, "ello") != 4) { + fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); + exit(1); + } + if (gzprintf(file, ", %s!", "hello") != 8) { + fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); + exit(1); + } + gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ + gzclose(file); + + file = gzopen(fname, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + strcpy((char*)uncompr, "garbage"); + + if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); + exit(1); + } else { + printf("gzread(): %s\n", (char*)uncompr); + } + + pos = gzseek(file, -8L, SEEK_CUR); + if (pos != 6 || gztell(file) != pos) { + fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", + (long)pos, (long)gztell(file)); + exit(1); + } + + if (gzgetc(file) != ' ') { + fprintf(stderr, "gzgetc error\n"); + exit(1); + } + + if (gzungetc(' ', file) != ' ') { + fprintf(stderr, "gzungetc error\n"); + exit(1); + } + + gzgets(file, (char*)uncompr, (int)uncomprLen); + if (strlen((char*)uncompr) != 7) { /* " hello!" */ + fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); + exit(1); + } + if (strcmp((char*)uncompr, hello + 6)) { + fprintf(stderr, "bad gzgets after gzseek\n"); + exit(1); + } else { + printf("gzgets() after gzseek: %s\n", (char*)uncompr); + } + + gzclose(file); +#endif +} + +#endif /* Z_SOLO */ + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + uLong len = (uLong)strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } else { + printf("inflate(): %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + c_stream.avail_in = (uInt)comprLen/2; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (uInt)uncomprLen; + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (uInt)uncomprLen; + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + comprLen/2) { + fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); + exit(1); + } else { + printf("large_inflate(): OK\n"); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr, comprLen) + Byte *compr; + uLong *comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + uInt len = (uInt)strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uInt)*comprLen; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ + err = inflateSync(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + exit(1); + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(compr, comprLen) + Byte *compr; + uLong comprLen; +{ + z_stream c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = deflateSetDictionary(&c_stream, + (const Bytef*)dictionary, (int)sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uInt)strlen(hello)+1; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate should report Z_STREAM_END\n"); + exit(1); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) + Byte *compr, *uncompr; + uLong comprLen, uncomprLen; +{ + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uInt)comprLen; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uInt)uncomprLen; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, + (int)sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } else { + printf("inflate with dictionary: %s\n", (char *)uncompr); + } +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + Byte *compr, *uncompr; + uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + uLong uncomprLen = comprLen; + static const char* myVersion = ZLIB_VERSION; + + if (zlibVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + + printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", + ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); + + compr = (Byte*)calloc((uInt)comprLen, 1); + uncompr = (Byte*)calloc((uInt)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == Z_NULL || uncompr == Z_NULL) { + printf("out of memory\n"); + exit(1); + } + +#ifdef Z_SOLO + argc = strlen(argv[0]); +#else + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + uncompr, uncomprLen); +#endif + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + return 0; +} diff --git a/libz/test/infcover.c b/libz/test/infcover.c new file mode 100644 index 000000000..fe3d9203a --- /dev/null +++ b/libz/test/infcover.c @@ -0,0 +1,671 @@ +/* infcover.c -- test zlib's inflate routines with full code coverage + * Copyright (C) 2011 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* to use, do: ./configure --cover && make cover */ + +#include +#include +#include +#include +#include "zlib.h" + +/* get definition of internal structure so we can mess with it (see pull()), + and so we can call inflate_trees() (see cover5()) */ +#define ZLIB_INTERNAL +#include "inftrees.h" +#include "inflate.h" + +#define local static + +/* -- memory tracking routines -- */ + +/* + These memory tracking routines are provided to zlib and track all of zlib's + allocations and deallocations, check for LIFO operations, keep a current + and high water mark of total bytes requested, optionally set a limit on the + total memory that can be allocated, and when done check for memory leaks. + + They are used as follows: + + z_stream strm; + mem_setup(&strm) initializes the memory tracking and sets the + zalloc, zfree, and opaque members of strm to use + memory tracking for all zlib operations on strm + mem_limit(&strm, limit) sets a limit on the total bytes requested -- a + request that exceeds this limit will result in an + allocation failure (returns NULL) -- setting the + limit to zero means no limit, which is the default + after mem_setup() + mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used + mem_high(&strm, "msg") prints to stderr "msg" and the high water mark + mem_done(&strm, "msg") ends memory tracking, releases all allocations + for the tracking as well as leaked zlib blocks, if + any. If there was anything unusual, such as leaked + blocks, non-FIFO frees, or frees of addresses not + allocated, then "msg" and information about the + problem is printed to stderr. If everything is + normal, nothing is printed. mem_done resets the + strm members to Z_NULL to use the default memory + allocation routines on the next zlib initialization + using strm. + */ + +/* these items are strung together in a linked list, one for each allocation */ +struct mem_item { + void *ptr; /* pointer to allocated memory */ + size_t size; /* requested size of allocation */ + struct mem_item *next; /* pointer to next item in list, or NULL */ +}; + +/* this structure is at the root of the linked list, and tracks statistics */ +struct mem_zone { + struct mem_item *first; /* pointer to first item in list, or NULL */ + size_t total, highwater; /* total allocations, and largest total */ + size_t limit; /* memory allocation limit, or 0 if no limit */ + int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */ +}; + +/* memory allocation routine to pass to zlib */ +local void *mem_alloc(void *mem, unsigned count, unsigned size) +{ + void *ptr; + struct mem_item *item; + struct mem_zone *zone = mem; + size_t len = count * (size_t)size; + + /* induced allocation failure */ + if (zone == NULL || (zone->limit && zone->total + len > zone->limit)) + return NULL; + + /* perform allocation using the standard library, fill memory with a + non-zero value to make sure that the code isn't depending on zeros */ + ptr = malloc(len); + if (ptr == NULL) + return NULL; + memset(ptr, 0xa5, len); + + /* create a new item for the list */ + item = malloc(sizeof(struct mem_item)); + if (item == NULL) { + free(ptr); + return NULL; + } + item->ptr = ptr; + item->size = len; + + /* insert item at the beginning of the list */ + item->next = zone->first; + zone->first = item; + + /* update the statistics */ + zone->total += item->size; + if (zone->total > zone->highwater) + zone->highwater = zone->total; + + /* return the allocated memory */ + return ptr; +} + +/* memory free routine to pass to zlib */ +local void mem_free(void *mem, void *ptr) +{ + struct mem_item *item, *next; + struct mem_zone *zone = mem; + + /* if no zone, just do a free */ + if (zone == NULL) { + free(ptr); + return; + } + + /* point next to the item that matches ptr, or NULL if not found -- remove + the item from the linked list if found */ + next = zone->first; + if (next) { + if (next->ptr == ptr) + zone->first = next->next; /* first one is it, remove from list */ + else { + do { /* search the linked list */ + item = next; + next = item->next; + } while (next != NULL && next->ptr != ptr); + if (next) { /* if found, remove from linked list */ + item->next = next->next; + zone->notlifo++; /* not a LIFO free */ + } + + } + } + + /* if found, update the statistics and free the item */ + if (next) { + zone->total -= next->size; + free(next); + } + + /* if not found, update the rogue count */ + else + zone->rogue++; + + /* in any case, do the requested free with the standard library function */ + free(ptr); +} + +/* set up a controlled memory allocation space for monitoring, set the stream + parameters to the controlled routines, with opaque pointing to the space */ +local void mem_setup(z_stream *strm) +{ + struct mem_zone *zone; + + zone = malloc(sizeof(struct mem_zone)); + assert(zone != NULL); + zone->first = NULL; + zone->total = 0; + zone->highwater = 0; + zone->limit = 0; + zone->notlifo = 0; + zone->rogue = 0; + strm->opaque = zone; + strm->zalloc = mem_alloc; + strm->zfree = mem_free; +} + +/* set a limit on the total memory allocation, or 0 to remove the limit */ +local void mem_limit(z_stream *strm, size_t limit) +{ + struct mem_zone *zone = strm->opaque; + + zone->limit = limit; +} + +/* show the current total requested allocations in bytes */ +local void mem_used(z_stream *strm, char *prefix) +{ + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total); +} + +/* show the high water allocation in bytes */ +local void mem_high(z_stream *strm, char *prefix) +{ + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater); +} + +/* release the memory allocation zone -- if there are any surprises, notify */ +local void mem_done(z_stream *strm, char *prefix) +{ + int count = 0; + struct mem_item *item, *next; + struct mem_zone *zone = strm->opaque; + + /* show high water mark */ + mem_high(strm, prefix); + + /* free leftover allocations and item structures, if any */ + item = zone->first; + while (item != NULL) { + free(item->ptr); + next = item->next; + free(item); + item = next; + count++; + } + + /* issue alerts about anything unexpected */ + if (count || zone->total) + fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n", + prefix, zone->total, count); + if (zone->notlifo) + fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo); + if (zone->rogue) + fprintf(stderr, "** %s: %d frees not recognized\n", + prefix, zone->rogue); + + /* free the zone and delete from the stream */ + free(zone); + strm->opaque = Z_NULL; + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; +} + +/* -- inflate test routines -- */ + +/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This + decodes liberally, in that hex digits can be adjacent, in which case two in + a row writes a byte. Or they can delimited by any non-hex character, where + the delimiters are ignored except when a single hex digit is followed by a + delimiter in which case that single digit writes a byte. The returned + data is allocated and must eventually be freed. NULL is returned if out of + memory. If the length is not needed, then len can be NULL. */ +local unsigned char *h2b(const char *hex, unsigned *len) +{ + unsigned char *in; + unsigned next, val; + + in = malloc((strlen(hex) + 1) >> 1); + if (in == NULL) + return NULL; + next = 0; + val = 1; + do { + if (*hex >= '0' && *hex <= '9') + val = (val << 4) + *hex - '0'; + else if (*hex >= 'A' && *hex <= 'F') + val = (val << 4) + *hex - 'A' + 10; + else if (*hex >= 'a' && *hex <= 'f') + val = (val << 4) + *hex - 'a' + 10; + else if (val != 1 && val < 32) /* one digit followed by delimiter */ + val += 240; /* make it look like two digits */ + if (val > 255) { /* have two digits */ + in[next++] = val & 0xff; /* save the decoded byte */ + val = 1; /* start over */ + } + } while (*hex++); /* go through the loop with the terminating null */ + if (len != NULL) + *len = next; + in = reallocf(in, next); + return in; +} + +/* generic inflate() run, where hex is the hexadecimal input data, what is the + text to include in an error message, step is how much input data to feed + inflate() on each call, or zero to feed it all, win is the window bits + parameter to inflateInit2(), len is the size of the output buffer, and err + is the error code expected from the first inflate() call (the second + inflate() call is expected to return Z_STREAM_END). If win is 47, then + header information is collected with inflateGetHeader(). If a zlib stream + is looking for a dictionary, then an empty dictionary is provided. + inflate() is run until all of the input data is consumed. */ +local void inf(char *hex, char *what, unsigned step, int win, unsigned len, + int err) +{ + int ret; + unsigned have; + unsigned char *in, *out; + z_stream strm, copy; + gz_header head; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, win); + if (ret != Z_OK) { + mem_done(&strm, what); + return; + } + out = malloc(len); assert(out != NULL); + if (win == 47) { + head.extra = out; + head.extra_max = len; + head.name = out; + head.name_max = len; + head.comment = out; + head.comm_max = len; + ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK); + } + in = h2b(hex, &have); assert(in != NULL); + if (step == 0 || step > have) + step = have; + strm.avail_in = step; + have -= step; + strm.next_in = in; + do { + strm.avail_out = len; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err); + if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT) + break; + if (ret == Z_NEED_DICT) { + ret = inflateSetDictionary(&strm, in, 1); + assert(ret == Z_DATA_ERROR); + mem_limit(&strm, 1); + ret = inflateSetDictionary(&strm, out, 0); + assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ((struct inflate_state *)strm.state)->mode = DICT; + ret = inflateSetDictionary(&strm, out, 0); + assert(ret == Z_OK); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR); + } + ret = inflateCopy(©, &strm); assert(ret == Z_OK); + ret = inflateEnd(©); assert(ret == Z_OK); + err = 9; /* don't care next time around */ + have += strm.avail_in; + strm.avail_in = step > have ? have : step; + have -= strm.avail_in; + } while (strm.avail_in); + free(in); + free(out); + ret = inflateReset2(&strm, -8); assert(ret == Z_OK); + ret = inflateEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, what); +} + +/* cover all of the lines in inflate.c up to inflate() */ +local void cover_support(void) +{ + int ret; + z_stream strm; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); assert(ret == Z_OK); + mem_used(&strm, "inflate init"); + ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK); + ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK); + ret = inflateSetDictionary(&strm, Z_NULL, 0); + assert(ret == Z_STREAM_ERROR); + ret = inflateEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, "prime"); + + inf("63 0", "force window allocation", 0, -15, 1, Z_OK); + inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK); + inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK); + inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END); + inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR); + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream)); + assert(ret == Z_VERSION_ERROR); + mem_done(&strm, "wrong version"); + + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); assert(ret == Z_OK); + ret = inflateEnd(&strm); assert(ret == Z_OK); + fputs("inflate built-in memory routines\n", stderr); +} + +/* cover all inflate() header and trailer cases and code after inflate() */ +local void cover_wrap(void) +{ + int ret; + z_stream strm, copy; + unsigned char dict[257]; + + ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR); + ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR); + ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflate bad parameters\n", stderr); + + inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR); + inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR); + inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR); + inf("8 99", "set window size from header", 0, 0, 0, Z_OK); + inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR); + inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END); + inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1, + Z_DATA_ERROR); + inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length", + 0, 47, 0, Z_STREAM_END); + inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR); + inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT); + inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK); + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, -8); + strm.avail_in = 2; + strm.next_in = (void *)"\x63"; + strm.avail_out = 1; + strm.next_out = (void *)&ret; + mem_limit(&strm, 1); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + memset(dict, 0, 257); + ret = inflateSetDictionary(&strm, dict, 257); + assert(ret == Z_OK); + mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256); + ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x80"; + ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR); + ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR); + strm.avail_in = 4; + strm.next_in = (void *)"\0\0\xff\xff"; + ret = inflateSync(&strm); assert(ret == Z_OK); + (void)inflateSyncPoint(&strm); + ret = inflateCopy(©, &strm); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR); + (void)inflateMark(&strm); + ret = inflateEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, "miscellaneous, force memory errors"); +} + +/* input and output functions for inflateBack() */ +local unsigned pull(void *desc, unsigned char **buf) +{ + static unsigned int next = 0; + static unsigned char dat[] = {0x63, 0, 2, 0}; + struct inflate_state *state; + + if (desc == Z_NULL) { + next = 0; + return 0; /* no input (already provided at next_in) */ + } + state = (void *)((z_stream *)desc)->state; + if (state != Z_NULL) + state->mode = SYNC; /* force an otherwise impossible situation */ + return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0; +} + +local int push(void *desc, unsigned char *buf, unsigned len) +{ + buf += len; + return desc != Z_NULL; /* force error if desc not null */ +} + +/* cover inflateBack() up to common deflate data cases and after those */ +local void cover_back(void) +{ + int ret; + z_stream strm; + unsigned char win[32768]; + + ret = inflateBackInit_(Z_NULL, 0, win, 0, 0); + assert(ret == Z_VERSION_ERROR); + ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR); + ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL); + assert(ret == Z_STREAM_ERROR); + ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflateBack bad parameters\n", stderr); + + mem_setup(&strm); + ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x03"; + ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL); + assert(ret == Z_STREAM_END); + /* force output error */ + strm.avail_in = 3; + strm.next_in = (void *)"\x63\x00"; + ret = inflateBack(&strm, pull, Z_NULL, push, &strm); + assert(ret == Z_BUF_ERROR); + /* force mode error by mucking with state */ + ret = inflateBack(&strm, pull, &strm, push, Z_NULL); + assert(ret == Z_STREAM_ERROR); + ret = inflateBackEnd(&strm); assert(ret == Z_OK); + mem_done(&strm, "inflateBack bad state"); + + ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK); + ret = inflateBackEnd(&strm); assert(ret == Z_OK); + fputs("inflateBack built-in memory routines\n", stderr); +} + +/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */ +local int try(char *hex, char *id, int err) +{ + int ret; + unsigned len, size; + unsigned char *in, *out, *win; + char *prefix; + z_stream strm; + + /* convert to hex */ + in = h2b(hex, &len); + assert(in != NULL); + + /* allocate work areas */ + size = len << 3; + out = malloc(size); + assert(out != NULL); + win = malloc(32768); + assert(win != NULL); + prefix = malloc(strlen(id) + 6); + assert(prefix != NULL); + + /* first with inflate */ + strcpy(prefix, id); + strcat(prefix, "-late"); + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, err < 0 ? 47 : -15); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + do { + strm.avail_out = size; + strm.next_out = out; + ret = inflate(&strm, Z_TREES); + assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR); + if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT) + break; + } while (strm.avail_in || strm.avail_out == 0); + if (err) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + inflateEnd(&strm); + mem_done(&strm, prefix); + + /* then with inflateBack */ + if (err >= 0) { + strcpy(prefix, id); + strcat(prefix, "-back"); + mem_setup(&strm); + ret = inflateBackInit(&strm, 15, win); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL); + assert(ret != Z_STREAM_ERROR); + if (err) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + inflateBackEnd(&strm); + mem_done(&strm, prefix); + } + + /* clean up */ + free(prefix); + free(win); + free(out); + free(in); + return ret; +} + +/* cover deflate data cases in both inflate() and inflateBack() */ +local void cover_inflate(void) +{ + try("0 0 0 0 0", "invalid stored block lengths", 1); + try("3 0", "fixed", 0); + try("6", "invalid block type", 1); + try("1 1 0 fe ff 0", "stored", 0); + try("fc 0 0", "too many length or distance symbols", 1); + try("4 0 fe ff", "invalid code lengths set", 1); + try("4 0 24 49 0", "invalid bit length repeat", 1); + try("4 0 24 e9 ff ff", "invalid bit length repeat", 1); + try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1); + try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0", + "invalid literal/lengths set", 1); + try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1); + try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1); + try("2 7e ff ff", "invalid distance code", 1); + try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1); + + /* also trailer mismatch just in inflate() */ + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1); + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1", + "incorrect length check", -1); + try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0); + try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f", + "long code", 0); + try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0); + try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c", + "long distance and extra", 0); + try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0); + inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258, + Z_STREAM_END); + inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK); +} + +/* cover remaining lines in inftrees.c */ +local void cover_trees(void) +{ + int ret; + unsigned bits; + unsigned short lens[16], work[16]; + code *next, table[ENOUGH_DISTS]; + + /* we need to call inflate_table() directly in order to manifest not- + enough errors, since zlib insures that enough is always enough */ + for (bits = 0; bits < 15; bits++) + lens[bits] = (unsigned short)(bits + 1); + lens[15] = 15; + next = table; + bits = 15; + ret = inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + next = table; + bits = 1; + ret = inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + fputs("inflate_table not enough errors\n", stderr); +} + +/* cover remaining inffast.c decoding and window copying */ +local void cover_fast(void) +{ + inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68" + " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR); + inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49" + " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258, + Z_DATA_ERROR); + inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258, + Z_DATA_ERROR); + inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258, + Z_DATA_ERROR); + inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0", + "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR); + inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK); + inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0", + "contiguous and wrap around window", 6, -8, 259, Z_OK); + inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259, + Z_STREAM_END); +} + +int main(void) +{ + fprintf(stderr, "%s\n", zlibVersion()); + cover_support(); + cover_wrap(); + cover_back(); + cover_inflate(); + cover_trees(); + cover_fast(); + return 0; +} diff --git a/libz/test/minigzip.c b/libz/test/minigzip.c new file mode 100644 index 000000000..b3025a489 --- /dev/null +++ b/libz/test/minigzip.c @@ -0,0 +1,651 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. On MSDOS, use only on file names without extension + * or in pipe mode. + */ + +/* @(#) $Id$ */ + +#include "zlib.h" +#include + +#ifdef STDC +# include +# include +#endif + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# ifdef UNDER_CE +# include +# endif +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +#ifdef VMS +# define unlink delete +# define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +# define unlink remove +# define GZ_SUFFIX "-gz" +# define fileno(file) file->__file +#endif +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fileno */ +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ + extern int unlink OF((const char *)); +#endif +#endif + +#if defined(UNDER_CE) +# include +# define perror(s) pwinerror(s) + +/* Map the Windows error number in ERROR to a locale-dependent error + message string and return a pointer to it. Typically, the values + for ERROR come from GetLastError. + + The string pointed to shall not be modified by the application, + but may be overwritten by a subsequent call to strwinerror + + The strwinerror function does not change the current setting + of GetLastError. */ + +static char *strwinerror (error) + DWORD error; +{ + static char buf[1024]; + + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > sizeof (buf) - 1) { + chars = sizeof (buf) - 1; + msgbuf[chars] = 0; + } + + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else { + sprintf(buf, "unknown win32 error (%ld)", error); + } + + SetLastError(lasterr); + return buf; +} + +static void pwinerror (s) + const char *s; +{ + if (s && *s) + fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); + else + fprintf(stderr, "%s\n", strwinerror(GetLastError ())); +} + +#endif /* UNDER_CE */ + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 +#define MAX_NAME_LEN 1024 + +#ifdef MAXSEG_64K +# define local static + /* Needed for systems with limitation on stack size. */ +#else +# define local +#endif + +#ifdef Z_SOLO +/* for Z_SOLO, create simplified gz* functions using deflate and inflate */ + +#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE) +# include /* for unlink() */ +#endif + +void *myalloc OF((void *, unsigned, unsigned)); +void myfree OF((void *, void *)); + +void *myalloc(q, n, m) + void *q; + unsigned n, m; +{ + q = Z_NULL; + return calloc(n, m); +} + +void myfree(q, p) + void *q, *p; +{ + q = Z_NULL; + free(p); +} + +typedef struct gzFile_s { + FILE *file; + int write; + int err; + char *msg; + z_stream strm; +} *gzFile; + +gzFile gzopen OF((const char *, const char *)); +gzFile gzdopen OF((int, const char *)); +gzFile gz_open OF((const char *, int, const char *)); + +gzFile gzopen(path, mode) +const char *path; +const char *mode; +{ + return gz_open(path, -1, mode); +} + +gzFile gzdopen(fd, mode) +int fd; +const char *mode; +{ + return gz_open(NULL, fd, mode); +} + +gzFile gz_open(path, fd, mode) + const char *path; + int fd; + const char *mode; +{ + gzFile gz; + int ret; + + gz = malloc(sizeof(struct gzFile_s)); + if (gz == NULL) + return NULL; + gz->write = strchr(mode, 'w') != NULL; + gz->strm.zalloc = myalloc; + gz->strm.zfree = myfree; + gz->strm.opaque = Z_NULL; + if (gz->write) + ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0); + else { + gz->strm.next_in = 0; + gz->strm.avail_in = Z_NULL; + ret = inflateInit2(&(gz->strm), 15 + 16); + } + if (ret != Z_OK) { + free(gz); + return NULL; + } + gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") : + fopen(path, gz->write ? "wb" : "rb"); + if (gz->file == NULL) { + gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm)); + free(gz); + return NULL; + } + gz->err = 0; + gz->msg = ""; + return gz; +} + +int gzwrite OF((gzFile, const void *, unsigned)); + +int gzwrite(gz, buf, len) + gzFile gz; + const void *buf; + unsigned len; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL || !gz->write) + return 0; + strm = &(gz->strm); + strm->next_in = (void *)buf; + strm->avail_in = len; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_NO_FLUSH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + return len; +} + +int gzread OF((gzFile, void *, unsigned)); + +int gzread(gz, buf, len) + gzFile gz; + void *buf; + unsigned len; +{ + int ret; + unsigned got; + unsigned char in[1]; + z_stream *strm; + + if (gz == NULL || gz->write) + return 0; + if (gz->err) + return 0; + strm = &(gz->strm); + strm->next_out = (void *)buf; + strm->avail_out = len; + do { + got = fread(in, 1, 1, gz->file); + if (got == 0) + break; + strm->next_in = in; + strm->avail_in = 1; + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_DATA_ERROR) { + gz->err = Z_DATA_ERROR; + gz->msg = strm->msg; + return 0; + } + if (ret == Z_STREAM_END) + inflateReset(strm); + } while (strm->avail_out); + return len - strm->avail_out; +} + +int gzclose OF((gzFile)); + +int gzclose(gz) + gzFile gz; +{ + z_stream *strm; + unsigned char out[BUFLEN]; + + if (gz == NULL) + return Z_STREAM_ERROR; + strm = &(gz->strm); + if (gz->write) { + strm->next_in = Z_NULL; + strm->avail_in = 0; + do { + strm->next_out = out; + strm->avail_out = BUFLEN; + (void)deflate(strm, Z_FINISH); + fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); + } while (strm->avail_out == 0); + deflateEnd(strm); + } + else + inflateEnd(strm); + fclose(gz->file); + free(gz); + return Z_OK; +} + +const char *gzerror OF((gzFile, int *)); + +const char *gzerror(gz, err) + gzFile gz; + int *err; +{ + *err = gz->err; + return gz->msg; +} + +#endif + +char *prog; + +void error OF((const char *msg)); +void gz_compress OF((FILE *in, gzFile out)); +#ifdef USE_MMAP +int gz_compress_mmap OF((FILE *in, gzFile out)); +#endif +void gz_uncompress OF((gzFile in, FILE *out)); +void file_compress OF((char *file, char *mode)); +void file_uncompress OF((char *file)); +int main OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + const char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + for (;;) { + len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(in, out) + FILE *in; + gzFile out; +{ + int len; + int err; + int ifd = fileno(in); + caddr_t buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (caddr_t)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = gzwrite(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(gzerror(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file, mode) + char *file; + char *mode; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); +#else + strcpy(outfile, file); + strcat(outfile, GZ_SUFFIX); +#endif + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(buf, sizeof(buf), "%s", file); +#else + strcpy(buf, file); +#endif + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); +#else + strcat(infile, GZ_SUFFIX); +#endif + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] + * -c : write to standard output + * -d : decompress + * -f : compress with Z_FILTERED + * -h : compress with Z_HUFFMAN_ONLY + * -r : compress with Z_RLE + * -1 to -9 : compression level + */ + +int main(argc, argv) + int argc; + char *argv[]; +{ + int copyout = 0; + int uncompr = 0; + gzFile file; + char *bname, outmode[20]; + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) + snprintf(outmode, sizeof(outmode), "%s", "wb6 "); +#else + strcpy(outmode, "wb6 "); +#endif + + prog = argv[0]; + bname = strrchr(argv[0], '/'); + if (bname) + bname++; + else + bname = argv[0]; + argc--, argv++; + + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + + while (argc > 0) { + if (strcmp(*argv, "-c") == 0) + copyout = 1; + else if (strcmp(*argv, "-d") == 0) + uncompr = 1; + else if (strcmp(*argv, "-f") == 0) + outmode[3] = 'f'; + else if (strcmp(*argv, "-h") == 0) + outmode[3] = 'h'; + else if (strcmp(*argv, "-r") == 0) + outmode[3] = 'R'; + else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && + (*argv)[2] == 0) + outmode[2] = (*argv)[1]; + else + break; + argc--, argv++; + } + if (outmode[3] == ' ') + outmode[3] = 0; + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } + do { + if (uncompr) { + if (copyout) { + file = gzopen(*argv, "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(*argv); + } + } else { + if (copyout) { + FILE * in = fopen(*argv, "rb"); + + if (in == NULL) { + perror(*argv); + } else { + file = gzdopen(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(*argv, outmode); + } + } + } while (argv++, --argc); + } + return 0; +} diff --git a/libz/treebuild.xml b/libz/treebuild.xml new file mode 100644 index 000000000..38d29d75e --- /dev/null +++ b/libz/treebuild.xml @@ -0,0 +1,116 @@ + + + + zip compression library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libz/trees.c b/libz/trees.c new file mode 100644 index 000000000..1fd7759ef --- /dev/null +++ b/libz/trees.c @@ -0,0 +1,1226 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2012 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, const ct_data *ltree, + const ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void ZLIB_INTERNAL _tr_flush_bits(s) + deflate_state *s; +{ + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + const ct_data *ltree; /* literal tree */ + const ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/libz/trees.h b/libz/trees.h new file mode 100644 index 000000000..d35639d82 --- /dev/null +++ b/libz/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/libz/uncompr.c b/libz/uncompr.c new file mode 100644 index 000000000..242e9493d --- /dev/null +++ b/libz/uncompr.c @@ -0,0 +1,59 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (z_const Bytef *)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/libz/watcom/watcom_f.mak b/libz/watcom/watcom_f.mak new file mode 100644 index 000000000..37f4d74c1 --- /dev/null +++ b/libz/watcom/watcom_f.mak @@ -0,0 +1,43 @@ +# Makefile for zlib +# OpenWatcom flat model +# Last updated: 28-Dec-2005 + +# To use, do "wmake -f watcom_f.mak" + +C_SOURCE = adler32.c compress.c crc32.c deflate.c & + gzclose.c gzlib.c gzread.c gzwrite.c & + infback.c inffast.c inflate.c inftrees.c & + trees.c uncompr.c zutil.c + +OBJS = adler32.obj compress.obj crc32.obj deflate.obj & + gzclose.obj gzlib.obj gzread.obj gzwrite.obj & + infback.obj inffast.obj inflate.obj inftrees.obj & + trees.obj uncompr.obj zutil.obj + +CC = wcc386 +LINKER = wcl386 +CFLAGS = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx +ZLIB_LIB = zlib_f.lib + +.C.OBJ: + $(CC) $(CFLAGS) $[@ + +all: $(ZLIB_LIB) example.exe minigzip.exe + +$(ZLIB_LIB): $(OBJS) + wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj + wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj + wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj + wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj + wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj + +example.exe: $(ZLIB_LIB) example.obj + $(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB) + +minigzip.exe: $(ZLIB_LIB) minigzip.obj + $(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB) + +clean: .SYMBOLIC + del *.obj + del $(ZLIB_LIB) + @echo Cleaning done diff --git a/libz/watcom/watcom_l.mak b/libz/watcom/watcom_l.mak new file mode 100644 index 000000000..193eed7b3 --- /dev/null +++ b/libz/watcom/watcom_l.mak @@ -0,0 +1,43 @@ +# Makefile for zlib +# OpenWatcom large model +# Last updated: 28-Dec-2005 + +# To use, do "wmake -f watcom_l.mak" + +C_SOURCE = adler32.c compress.c crc32.c deflate.c & + gzclose.c gzlib.c gzread.c gzwrite.c & + infback.c inffast.c inflate.c inftrees.c & + trees.c uncompr.c zutil.c + +OBJS = adler32.obj compress.obj crc32.obj deflate.obj & + gzclose.obj gzlib.obj gzread.obj gzwrite.obj & + infback.obj inffast.obj inflate.obj inftrees.obj & + trees.obj uncompr.obj zutil.obj + +CC = wcc +LINKER = wcl +CFLAGS = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx +ZLIB_LIB = zlib_l.lib + +.C.OBJ: + $(CC) $(CFLAGS) $[@ + +all: $(ZLIB_LIB) example.exe minigzip.exe + +$(ZLIB_LIB): $(OBJS) + wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj + wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj + wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj + wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj + wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj + +example.exe: $(ZLIB_LIB) example.obj + $(LINKER) -fe=example.exe example.obj $(ZLIB_LIB) + +minigzip.exe: $(ZLIB_LIB) minigzip.obj + $(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB) + +clean: .SYMBOLIC + del *.obj + del $(ZLIB_LIB) + @echo Cleaning done diff --git a/libz/win32/DLL_FAQ.txt b/libz/win32/DLL_FAQ.txt new file mode 100644 index 000000000..12c009018 --- /dev/null +++ b/libz/win32/DLL_FAQ.txt @@ -0,0 +1,397 @@ + + Frequently Asked Questions about ZLIB1.DLL + + +This document describes the design, the rationale, and the usage +of the official DLL build of zlib, named ZLIB1.DLL. If you have +general questions about zlib, you should see the file "FAQ" found +in the zlib distribution, or at the following location: + http://www.gzip.org/zlib/zlib_faq.html + + + 1. What is ZLIB1.DLL, and how can I get it? + + - ZLIB1.DLL is the official build of zlib as a DLL. + (Please remark the character '1' in the name.) + + Pointers to a precompiled ZLIB1.DLL can be found in the zlib + web site at: + http://www.zlib.net/ + + Applications that link to ZLIB1.DLL can rely on the following + specification: + + * The exported symbols are exclusively defined in the source + files "zlib.h" and "zlib.def", found in an official zlib + source distribution. + * The symbols are exported by name, not by ordinal. + * The exported names are undecorated. + * The calling convention of functions is "C" (CDECL). + * The ZLIB1.DLL binary is linked to MSVCRT.DLL. + + The archive in which ZLIB1.DLL is bundled contains compiled + test programs that must run with a valid build of ZLIB1.DLL. + It is recommended to download the prebuilt DLL from the zlib + web site, instead of building it yourself, to avoid potential + incompatibilities that could be introduced by your compiler + and build settings. If you do build the DLL yourself, please + make sure that it complies with all the above requirements, + and it runs with the precompiled test programs, bundled with + the original ZLIB1.DLL distribution. + + If, for any reason, you need to build an incompatible DLL, + please use a different file name. + + + 2. Why did you change the name of the DLL to ZLIB1.DLL? + What happened to the old ZLIB.DLL? + + - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required + compilation settings that were incompatible to those used by + a static build. The DLL settings were supposed to be enabled + by defining the macro ZLIB_DLL, before including "zlib.h". + Incorrect handling of this macro was silently accepted at + build time, resulting in two major problems: + + * ZLIB_DLL was missing from the old makefile. When building + the DLL, not all people added it to the build options. In + consequence, incompatible incarnations of ZLIB.DLL started + to circulate around the net. + + * When switching from using the static library to using the + DLL, applications had to define the ZLIB_DLL macro and + to recompile all the sources that contained calls to zlib + functions. Failure to do so resulted in creating binaries + that were unable to run with the official ZLIB.DLL build. + + The only possible solution that we could foresee was to make + a binary-incompatible change in the DLL interface, in order to + remove the dependency on the ZLIB_DLL macro, and to release + the new DLL under a different name. + + We chose the name ZLIB1.DLL, where '1' indicates the major + zlib version number. We hope that we will not have to break + the binary compatibility again, at least not as long as the + zlib-1.x series will last. + + There is still a ZLIB_DLL macro, that can trigger a more + efficient build and use of the DLL, but compatibility no + longer dependents on it. + + + 3. Can I build ZLIB.DLL from the new zlib sources, and replace + an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier? + + - In principle, you can do it by assigning calling convention + keywords to the macros ZEXPORT and ZEXPORTVA. In practice, + it depends on what you mean by "an old ZLIB.DLL", because the + old DLL exists in several mutually-incompatible versions. + You have to find out first what kind of calling convention is + being used in your particular ZLIB.DLL build, and to use the + same one in the new build. If you don't know what this is all + about, you might be better off if you would just leave the old + DLL intact. + + + 4. Can I compile my application using the new zlib interface, and + link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or + earlier? + + - The official answer is "no"; the real answer depends again on + what kind of ZLIB.DLL you have. Even if you are lucky, this + course of action is unreliable. + + If you rebuild your application and you intend to use a newer + version of zlib (post- 1.1.4), it is strongly recommended to + link it to the new ZLIB1.DLL. + + + 5. Why are the zlib symbols exported by name, and not by ordinal? + + - Although exporting symbols by ordinal is a little faster, it + is risky. Any single glitch in the maintenance or use of the + DEF file that contains the ordinals can result in incompatible + builds and frustrating crashes. Simply put, the benefits of + exporting symbols by ordinal do not justify the risks. + + Technically, it should be possible to maintain ordinals in + the DEF file, and still export the symbols by name. Ordinals + exist in every DLL, and even if the dynamic linking performed + at the DLL startup is searching for names, ordinals serve as + hints, for a faster name lookup. However, if the DEF file + contains ordinals, the Microsoft linker automatically builds + an implib that will cause the executables linked to it to use + those ordinals, and not the names. It is interesting to + notice that the GNU linker for Win32 does not suffer from this + problem. + + It is possible to avoid the DEF file if the exported symbols + are accompanied by a "__declspec(dllexport)" attribute in the + source files. You can do this in zlib by predefining the + ZLIB_DLL macro. + + + 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling + convention. Why not use the STDCALL convention? + STDCALL is the standard convention in Win32, and I need it in + my Visual Basic project! + + (For readability, we use CDECL to refer to the convention + triggered by the "__cdecl" keyword, STDCALL to refer to + the convention triggered by "__stdcall", and FASTCALL to + refer to the convention triggered by "__fastcall".) + + - Most of the native Windows API functions (without varargs) use + indeed the WINAPI convention (which translates to STDCALL in + Win32), but the standard C functions use CDECL. If a user + application is intrinsically tied to the Windows API (e.g. + it calls native Windows API functions such as CreateFile()), + sometimes it makes sense to decorate its own functions with + WINAPI. But if ANSI C or POSIX portability is a goal (e.g. + it calls standard C functions such as fopen()), it is not a + sound decision to request the inclusion of , or to + use non-ANSI constructs, for the sole purpose to make the user + functions STDCALL-able. + + The functionality offered by zlib is not in the category of + "Windows functionality", but is more like "C functionality". + + Technically, STDCALL is not bad; in fact, it is slightly + faster than CDECL, and it works with variable-argument + functions, just like CDECL. It is unfortunate that, in spite + of using STDCALL in the Windows API, it is not the default + convention used by the C compilers that run under Windows. + The roots of the problem reside deep inside the unsafety of + the K&R-style function prototypes, where the argument types + are not specified; but that is another story for another day. + + The remaining fact is that CDECL is the default convention. + Even if an explicit convention is hard-coded into the function + prototypes inside C headers, problems may appear. The + necessity to expose the convention in users' callbacks is one + of these problems. + + The calling convention issues are also important when using + zlib in other programming languages. Some of them, like Ada + (GNAT) and Fortran (GNU G77), have C bindings implemented + initially on Unix, and relying on the C calling convention. + On the other hand, the pre- .NET versions of Microsoft Visual + Basic require STDCALL, while Borland Delphi prefers, although + it does not require, FASTCALL. + + In fairness to all possible uses of zlib outside the C + programming language, we choose the default "C" convention. + Anyone interested in different bindings or conventions is + encouraged to maintain specialized projects. The "contrib/" + directory from the zlib distribution already holds a couple + of foreign bindings, such as Ada, C++, and Delphi. + + + 7. I need a DLL for my Visual Basic project. What can I do? + + - Define the ZLIB_WINAPI macro before including "zlib.h", when + building both the DLL and the user application (except that + you don't need to define anything when using the DLL in Visual + Basic). The ZLIB_WINAPI macro will switch on the WINAPI + (STDCALL) convention. The name of this DLL must be different + than the official ZLIB1.DLL. + + Gilles Vollant has contributed a build named ZLIBWAPI.DLL, + with the ZLIB_WINAPI macro turned on, and with the minizip + functionality built in. For more information, please read + the notes inside "contrib/vstudio/readme.txt", found in the + zlib distribution. + + + 8. I need to use zlib in my Microsoft .NET project. What can I + do? + + - Henrik Ravn has contributed a .NET wrapper around zlib. Look + into contrib/dotzlib/, inside the zlib distribution. + + + 9. If my application uses ZLIB1.DLL, should I link it to + MSVCRT.DLL? Why? + + - It is not required, but it is recommended to link your + application to MSVCRT.DLL, if it uses ZLIB1.DLL. + + The executables (.EXE, .DLL, etc.) that are involved in the + same process and are using the C run-time library (i.e. they + are calling standard C functions), must link to the same + library. There are several libraries in the Win32 system: + CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc. + Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that + depend on it should also be linked to MSVCRT.DLL. + + +10. Why are you saying that ZLIB1.DLL and my application should + be linked to the same C run-time (CRT) library? I linked my + application and my DLLs to different C libraries (e.g. my + application to a static library, and my DLLs to MSVCRT.DLL), + and everything works fine. + + - If a user library invokes only pure Win32 API (accessible via + and the related headers), its DLL build will work + in any context. But if this library invokes standard C API, + things get more complicated. + + There is a single Win32 library in a Win32 system. Every + function in this library resides in a single DLL module, that + is safe to call from anywhere. On the other hand, there are + multiple versions of the C library, and each of them has its + own separate internal state. Standalone executables and user + DLLs that call standard C functions must link to a C run-time + (CRT) library, be it static or shared (DLL). Intermixing + occurs when an executable (not necessarily standalone) and a + DLL are linked to different CRTs, and both are running in the + same process. + + Intermixing multiple CRTs is possible, as long as their + internal states are kept intact. The Microsoft Knowledge Base + articles KB94248 "HOWTO: Use the C Run-Time" and KB140584 + "HOWTO: Link with the Correct C Run-Time (CRT) Library" + mention the potential problems raised by intermixing. + + If intermixing works for you, it's because your application + and DLLs are avoiding the corruption of each of the CRTs' + internal states, maybe by careful design, or maybe by fortune. + + Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such + as those provided by Borland, raises similar problems. + + +11. Why are you linking ZLIB1.DLL to MSVCRT.DLL? + + - MSVCRT.DLL exists on every Windows 95 with a new service pack + installed, or with Microsoft Internet Explorer 4 or later, and + on all other Windows 4.x or later (Windows 98, Windows NT 4, + or later). It is freely distributable; if not present in the + system, it can be downloaded from Microsoft or from other + software provider for free. + + The fact that MSVCRT.DLL does not exist on a virgin Windows 95 + is not so problematic. Windows 95 is scarcely found nowadays, + Microsoft ended its support a long time ago, and many recent + applications from various vendors, including Microsoft, do not + even run on it. Furthermore, no serious user should run + Windows 95 without a proper update installed. + + +12. Why are you not linking ZLIB1.DLL to + <> ? + + - We considered and abandoned the following alternatives: + + * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or + LIBCMT.LIB) is not a good option. People are using the DLL + mainly to save disk space. If you are linking your program + to a static C library, you may as well consider linking zlib + in statically, too. + + * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because + CRTDLL.DLL is present on every Win32 installation. + Unfortunately, it has a series of problems: it does not + work properly with Microsoft's C++ libraries, it does not + provide support for 64-bit file offsets, (and so on...), + and Microsoft discontinued its support a long time ago. + + * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied + with the Microsoft .NET platform, and Visual C++ 7.0/7.1, + raises problems related to the status of ZLIB1.DLL as a + system component. According to the Microsoft Knowledge Base + article KB326922 "INFO: Redistribution of the Shared C + Runtime Component in Visual C++ .NET", MSVCR70.DLL and + MSVCR71.DLL are not supposed to function as system DLLs, + because they may clash with MSVCRT.DLL. Instead, the + application's installer is supposed to put these DLLs + (if needed) in the application's private directory. + If ZLIB1.DLL depends on a non-system runtime, it cannot + function as a redistributable system component. + + * Linking ZLIB1.DLL to non-Microsoft runtimes, such as + Borland's, or Cygwin's, raises problems related to the + reliable presence of these runtimes on Win32 systems. + It's easier to let the DLL build of zlib up to the people + who distribute these runtimes, and who may proceed as + explained in the answer to Question 14. + + +13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL, + how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0 + (Visual Studio .NET) or newer? + + - Due to the problems explained in the Microsoft Knowledge Base + article KB326922 (see the previous answer), the C runtime that + comes with the VC7 environment is no longer considered a + system component. That is, it should not be assumed that this + runtime exists, or may be installed in a system directory. + Since ZLIB1.DLL is supposed to be a system component, it may + not depend on a non-system component. + + In order to link ZLIB1.DLL and your application to MSVCRT.DLL + in VC7, you need the library of Visual C++ 6.0 or older. If + you don't have this library at hand, it's probably best not to + use ZLIB1.DLL. + + We are hoping that, in the future, Microsoft will provide a + way to build applications linked to a proper system runtime, + from the Visual C++ environment. Until then, you have a + couple of alternatives, such as linking zlib in statically. + If your application requires dynamic linking, you may proceed + as explained in the answer to Question 14. + + +14. I need to link my own DLL build to a CRT different than + MSVCRT.DLL. What can I do? + + - Feel free to rebuild the DLL from the zlib sources, and link + it the way you want. You should, however, clearly state that + your build is unofficial. You should give it a different file + name, and/or install it in a private directory that can be + accessed by your application only, and is not visible to the + others (i.e. it's neither in the PATH, nor in the SYSTEM or + SYSTEM32 directories). Otherwise, your build may clash with + applications that link to the official build. + + For example, in Cygwin, zlib is linked to the Cygwin runtime + CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. + + +15. May I include additional pieces of code that I find useful, + link them in ZLIB1.DLL, and export them? + + - No. A legitimate build of ZLIB1.DLL must not include code + that does not originate from the official zlib source code. + But you can make your own private DLL build, under a different + file name, as suggested in the previous answer. + + For example, zlib is a part of the VCL library, distributed + with Borland Delphi and C++ Builder. The DLL build of VCL + is a redistributable file, named VCLxx.DLL. + + +16. May I remove some functionality out of ZLIB1.DLL, by enabling + macros like NO_GZCOMPRESS or NO_GZIP at compile time? + + - No. A legitimate build of ZLIB1.DLL must provide the complete + zlib functionality, as implemented in the official zlib source + code. But you can make your own private DLL build, under a + different file name, as suggested in the previous answer. + + +17. I made my own ZLIB1.DLL build. Can I test it for compliance? + + - We prefer that you download the official DLL from the zlib + web site. If you need something peculiar from this DLL, you + can send your suggestion to the zlib mailing list. + + However, in case you do rebuild the DLL yourself, you can run + it with the test programs found in the DLL distribution. + Running these test programs is not a guarantee of compliance, + but a failure can imply a detected problem. + +** + +This document is written and maintained by +Cosmin Truta diff --git a/libz/win32/Makefile.bor b/libz/win32/Makefile.bor new file mode 100644 index 000000000..d152bbb7f --- /dev/null +++ b/libz/win32/Makefile.bor @@ -0,0 +1,110 @@ +# Makefile for zlib +# Borland C++ for Win32 +# +# Usage: +# make -f win32/Makefile.bor +# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj + +# ------------ Borland C++ ------------ + +# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) +# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or +# added to the declaration of LOC here: +LOC = $(LOCAL_ZLIB) + +CC = bcc32 +AS = bcc32 +LD = bcc32 +AR = tlib +CFLAGS = -a -d -k- -O2 $(LOC) +ASFLAGS = $(LOC) +LDFLAGS = $(LOC) + + +# variables +ZLIB_LIB = zlib.lib + +OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj +OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj +#OBJA = +OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj +OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj +#OBJPA= + + +# targets +all: $(ZLIB_LIB) example.exe minigzip.exe + +.c.obj: + $(CC) -c $(CFLAGS) $< + +.asm.obj: + $(AS) -c $(ASFLAGS) $< + +adler32.obj: adler32.c zlib.h zconf.h + +compress.obj: compress.c zlib.h zconf.h + +crc32.obj: crc32.c zlib.h zconf.h crc32.h + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + +gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h + +gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h + +gzread.obj: gzread.c zlib.h zconf.h gzguts.h + +gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h + +infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h + +inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ + inffast.h inffixed.h + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + +trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h + +uncompr.obj: uncompr.c zlib.h zconf.h + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + +example.obj: test/example.c zlib.h zconf.h + +minigzip.obj: test/minigzip.c zlib.h zconf.h + + +# For the sake of the old Borland make, +# the command line is cut to fit in the MS-DOS 128 byte limit: +$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA) + -del $(ZLIB_LIB) + $(AR) $(ZLIB_LIB) $(OBJP1) + $(AR) $(ZLIB_LIB) $(OBJP2) + $(AR) $(ZLIB_LIB) $(OBJPA) + + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +example.exe: example.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) + +minigzip.exe: minigzip.obj $(ZLIB_LIB) + $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) + + +# cleanup +clean: + -del $(ZLIB_LIB) + -del *.obj + -del *.exe + -del *.tds + -del zlib.bak + -del foo.gz diff --git a/libz/win32/Makefile.gcc b/libz/win32/Makefile.gcc new file mode 100644 index 000000000..6d1ded622 --- /dev/null +++ b/libz/win32/Makefile.gcc @@ -0,0 +1,182 @@ +# Makefile for zlib, derived from Makefile.dj2. +# Modified for mingw32 by C. Spieler, 6/16/98. +# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003. +# Last updated: Mar 2012. +# Tested under Cygwin and MinGW. + +# Copyright (C) 1995-2003 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile, or to compile and test, type from the top level zlib directory: +# +# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc +# +# To use the asm code, type: +# cp contrib/asm?86/match.S ./match.S +# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc +# +# To install libz.a, zconf.h and zlib.h in the system directories, type: +# +# make install -fwin32/Makefile.gcc +# +# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set. +# +# To install the shared lib, append SHARED_MODE=1 to the make command : +# +# make install -fwin32/Makefile.gcc SHARED_MODE=1 + +# Note: +# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN), +# the DLL name should be changed from "zlib1.dll". + +STATICLIB = libz.a +SHAREDLIB = zlib1.dll +IMPLIB = libz.dll.a + +# +# Set to 1 if shared object needs to be installed +# +SHARED_MODE=0 + +#LOC = -DASMV +#LOC = -DDEBUG -g + +PREFIX = +CC = $(PREFIX)gcc +CFLAGS = $(LOC) -O3 -Wall + +AS = $(CC) +ASFLAGS = $(LOC) -Wall + +LD = $(CC) +LDFLAGS = $(LOC) + +AR = $(PREFIX)ar +ARFLAGS = rcs + +RC = $(PREFIX)windres +RCFLAGS = --define GCC_WINDRES + +STRIP = $(PREFIX)strip + +CP = cp -fp +# If GNU install is available, replace $(CP) with install. +INSTALL = $(CP) +RM = rm -f + +prefix ?= /usr/local +exec_prefix = $(prefix) + +OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ + gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o +OBJA = + +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe + +test: example.exe minigzip.exe + ./example + echo hello world | ./minigzip | ./minigzip -d + +testdll: example_d.exe minigzip_d.exe + ./example_d + echo hello world | ./minigzip_d | ./minigzip_d -d + +.c.o: + $(CC) $(CFLAGS) -c -o $@ $< + +.S.o: + $(AS) $(ASFLAGS) -c -o $@ $< + +$(STATICLIB): $(OBJS) $(OBJA) + $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o + $(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \ + -o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o + $(STRIP) $@ + +example.exe: example.o $(STATICLIB) + $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB) + $(STRIP) $@ + +minigzip.exe: minigzip.o $(STATICLIB) + $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB) + $(STRIP) $@ + +example_d.exe: example.o $(IMPLIB) + $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB) + $(STRIP) $@ + +minigzip_d.exe: minigzip.o $(IMPLIB) + $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB) + $(STRIP) $@ + +example.o: test/example.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/example.c + +minigzip.o: test/minigzip.c zlib.h zconf.h + $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c + +zlibrc.o: win32/zlib1.rc + $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc + +.PHONY: install uninstall clean + +install: zlib.h zconf.h $(STATICLIB) $(IMPLIB) + @if test -z "$(DESTDIR)$(INCLUDE_PATH)" -o -z "$(DESTDIR)$(LIBRARY_PATH)" -o -z "$(DESTDIR)$(BINARY_PATH)"; then \ + echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \ + exit 1; \ + fi + -@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)' + -@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig + -if [ "$(SHARED_MODE)" = "1" ]; then \ + mkdir -p '$(DESTDIR)$(BINARY_PATH)'; \ + $(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \ + $(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \ + fi + -$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)' + -$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)' + -$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)' + sed \ + -e 's|@prefix@|${prefix}|g' \ + -e 's|@exec_prefix@|${exec_prefix}|g' \ + -e 's|@libdir@|$(LIBRARY_PATH)|g' \ + -e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \ + -e 's|@includedir@|$(INCLUDE_PATH)|g' \ + -e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \ + zlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc + +uninstall: + -if [ "$(SHARED_MODE)" = "1" ]; then \ + $(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \ + $(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \ + fi + -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h + -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h + -$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB) + +clean: + -$(RM) $(STATICLIB) + -$(RM) $(SHAREDLIB) + -$(RM) $(IMPLIB) + -$(RM) *.o + -$(RM) *.exe + -$(RM) foo.gz + +adler32.o: zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: crc32.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +gzclose.o: zlib.h zconf.h gzguts.h +gzlib.o: zlib.h zconf.h gzguts.h +gzread.o: zlib.h zconf.h gzguts.h +gzwrite.o: zlib.h zconf.h gzguts.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +trees.o: deflate.h zutil.h zlib.h zconf.h trees.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h diff --git a/libz/win32/Makefile.msc b/libz/win32/Makefile.msc new file mode 100644 index 000000000..67b773171 --- /dev/null +++ b/libz/win32/Makefile.msc @@ -0,0 +1,163 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.msc (standard build) +# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build) +# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \ +# OBJA="inffas32.obj match686.obj" (use ASM code, x86) +# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \ +# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib + +CC = cl +AS = ml +LD = link +AR = lib +RC = rc +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE +ASFLAGS = -coff -Zi $(LOC) +LDFLAGS = -nologo -debug -incremental:no -opt:ref +ARFLAGS = -nologo +RCFLAGS = /dWIN32 /r + +OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \ + gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj +OBJA = + + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +$(STATICLIB): $(OBJS) $(OBJA) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res + $(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \ + -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/contrib/masmx64}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/contrib/masmx64}.asm.obj: + $(AS) -c $(ASFLAGS) $< + +{$(TOP)/contrib/masmx86}.asm.obj: + $(AS) -c $(ASFLAGS) $< + +adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h + +compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h + +crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h + +deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h + +gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h + +gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h + +gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h + +gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h + +infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ + $(TOP)/inffast.h $(TOP)/inffixed.h + +inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ + $(TOP)/inffast.h + +inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ + $(TOP)/inffast.h $(TOP)/inffixed.h + +inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h + +trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h + +uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h + +zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h + +gvmat64.obj: $(TOP)/contrib\masmx64\gvmat64.asm + +inffasx64.obj: $(TOP)/contrib\masmx64\inffasx64.asm + +inffas8664.obj: $(TOP)/contrib\masmx64\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \ + $(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h + +inffas32.obj: $(TOP)/contrib\masmx86\inffas32.asm + +match686.obj: $(TOP)/contrib\masmx86\match686.asm + +example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h + +zlib1.res: $(TOP)/win32/zlib1.rc + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + -del foo.gz diff --git a/libz/win32/README-WIN32.txt b/libz/win32/README-WIN32.txt new file mode 100644 index 000000000..3d77d521e --- /dev/null +++ b/libz/win32/README-WIN32.txt @@ -0,0 +1,103 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.8 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). Two compiled +examples are distributed in this package, example and minigzip. The example_d +and minigzip_d flavors validate that the zlib1.dll file is working correctly. + +Questions about zlib should be sent to . The zlib home page +is http://zlib.net/ . Before reporting a problem, please check this site to +verify that you have the latest version of zlib; otherwise get the latest +version and check whether the problem still exists or not. + +PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html +before asking for help. + + +Manifest: + +The package zlib-1.2.8-win32-x86.zip will contain the following files: + + README-WIN32.txt This document + ChangeLog Changes since previous zlib packages + DLL_FAQ.txt Frequently asked questions about zlib1.dll + zlib.3.pdf Documentation of this library in Adobe Acrobat format + + example.exe A statically-bound example (using zlib.lib, not the dll) + example.pdb Symbolic information for debugging example.exe + + example_d.exe A zlib1.dll bound example (using zdll.lib) + example_d.pdb Symbolic information for debugging example_d.exe + + minigzip.exe A statically-bound test program (using zlib.lib, not the dll) + minigzip.pdb Symbolic information for debugging minigzip.exe + + minigzip_d.exe A zlib1.dll bound test program (using zdll.lib) + minigzip_d.pdb Symbolic information for debugging minigzip_d.exe + + zlib.h Install these files into the compilers' INCLUDE path to + zconf.h compile programs which use zlib.lib or zdll.lib + + zdll.lib Install these files into the compilers' LIB path if linking + zdll.exp a compiled program to the zlib1.dll binary + + zlib.lib Install these files into the compilers' LIB path to link zlib + zlib.pdb into compiled programs, without zlib1.dll runtime dependency + (zlib.pdb provides debugging info to the compile time linker) + + zlib1.dll Install this binary shared library into the system PATH, or + the program's runtime directory (where the .exe resides) + zlib1.pdb Install in the same directory as zlib1.dll, in order to debug + an application crash using WinDbg or similar tools. + +All .pdb files above are entirely optional, but are very useful to a developer +attempting to diagnose program misbehavior or a crash. Many additional +important files for developers can be found in the zlib127.zip source package +available from http://zlib.net/ - review that package's README file for details. + + +Acknowledgments: + +The deflate format used by zlib was defined by Phil Katz. The deflate and +zlib specifications were written by L. Peter Deutsch. Thanks to all the +people who reported problems and suggested various improvements in zlib; they +are too numerous to cite here. + + +Copyright notice: + + (C) 1995-2012 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. diff --git a/libz/win32/VisualC.txt b/libz/win32/VisualC.txt new file mode 100644 index 000000000..579a5fc9e --- /dev/null +++ b/libz/win32/VisualC.txt @@ -0,0 +1,3 @@ + +To build zlib using the Microsoft Visual C++ environment, +use the appropriate project from the projects/ directory. diff --git a/libz/win32/zlib.def b/libz/win32/zlib.def new file mode 100644 index 000000000..face65518 --- /dev/null +++ b/libz/win32/zlib.def @@ -0,0 +1,86 @@ +; zlib data compression library +EXPORTS +; basic functions + zlibVersion + deflate + deflateEnd + inflate + inflateEnd +; advanced functions + deflateSetDictionary + deflateCopy + deflateReset + deflateParams + deflateTune + deflateBound + deflatePending + deflatePrime + deflateSetHeader + inflateSetDictionary + inflateGetDictionary + inflateSync + inflateCopy + inflateReset + inflateReset2 + inflatePrime + inflateMark + inflateGetHeader + inflateBack + inflateBackEnd + zlibCompileFlags +; utility functions + compress + compress2 + compressBound + uncompress + gzopen + gzdopen + gzbuffer + gzsetparams + gzread + gzwrite + gzprintf + gzvprintf + gzputs + gzgets + gzputc + gzgetc + gzungetc + gzflush + gzseek + gzrewind + gztell + gzoffset + gzeof + gzdirect + gzclose + gzclose_r + gzclose_w + gzerror + gzclearerr +; large file functions + gzopen64 + gzseek64 + gztell64 + gzoffset64 + adler32_combine64 + crc32_combine64 +; checksum functions + adler32 + crc32 + adler32_combine + crc32_combine +; various hacks, don't look :) + deflateInit_ + deflateInit2_ + inflateInit_ + inflateInit2_ + inflateBackInit_ + gzgetc_ + zError + inflateSyncPoint + get_crc_table + inflateUndermine + inflateResetKeep + deflateResetKeep + gzopen_w diff --git a/libz/win32/zlib1.rc b/libz/win32/zlib1.rc new file mode 100644 index 000000000..5c0feed1b --- /dev/null +++ b/libz/win32/zlib1.rc @@ -0,0 +1,40 @@ +#include +#include "../zlib.h" + +#ifdef GCC_WINDRES +VS_VERSION_INFO VERSIONINFO +#else +VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE +#endif + FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIB_VERSION "\0" + VALUE "InternalName", "zlib1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIB_VERSION "\0" + VALUE "Comments", "For more information visit http://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/libz/zconf.h b/libz/zconf.h new file mode 100755 index 000000000..e1a6e7a4a --- /dev/null +++ b/libz/zconf.h @@ -0,0 +1,511 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#if 0 /* was set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#if 1 /* was set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/libz/zconf.h.cmakein b/libz/zconf.h.cmakein new file mode 100644 index 000000000..043019cda --- /dev/null +++ b/libz/zconf.h.cmakein @@ -0,0 +1,513 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H +#cmakedefine Z_PREFIX +#cmakedefine Z_HAVE_UNISTD_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/libz/zconf.h.in b/libz/zconf.h.in new file mode 100644 index 000000000..9987a7755 --- /dev/null +++ b/libz/zconf.h.in @@ -0,0 +1,511 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzvprintf z_gzvprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateGetDictionary z_inflateGetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateResetKeep z_inflateResetKeep +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +#ifndef Z_ARG /* function prototypes for stdarg */ +# if defined(STDC) || defined(Z_HAVE_STDARG_H) +# define Z_ARG(args) args +# else +# define Z_ARG(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) +# define Z_HAVE_UNISTD_H +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/libz/zlib.3 b/libz/zlib.3 new file mode 100644 index 000000000..0160e62b6 --- /dev/null +++ b/libz/zlib.3 @@ -0,0 +1,151 @@ +.TH ZLIB 3 "28 Apr 2013" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe, assuming that the standard library functions +used are thread safe, such as memory allocation routines. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms may be added later +with the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.IR gzip (1) +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. +The decoder checks the consistency of the compressed data, +so the library should never crash even in the case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h . +The distribution source includes examples of use of the library +in the files +.I test/example.c +and +.IR test/minigzip.c, +as well as other examples in the +.IR examples/ +directory. +.LP +Changes to this version are documented in the file +.I ChangeLog +that accompanies the source. +.LP +.I zlib +is available in Java using the java.util.zip package: +.IP +http://java.sun.com/developer/technicalArticles/Programming/compression/ +.LP +A Perl interface to +.IR zlib , +written by Paul Marquess (pmqs@cpan.org), +is available at CPAN (Comprehensive Perl Archive Network) sites, +including: +.IP +http://search.cpan.org/~pmqs/IO-Compress-Zlib/ +.LP +A Python interface to +.IR zlib , +written by A.M. Kuchling (amk@magnet.com), +is available in Python 1.5 and later versions: +.IP +http://docs.python.org/library/zlib.html +.LP +.I zlib +is built into +.IR tcl: +.IP +http://wiki.tcl.tk/4610 +.LP +An experimental package to read and write files in .zip format, +written on top of +.I zlib +by Gilles Vollant (info@winimage.com), +is available at: +.IP +http://www.winimage.com/zLibDll/minizip.html +and also in the +.I contrib/minizip +directory of the main +.I zlib +source distribution. +.SH "SEE ALSO" +The +.I zlib +web site can be found at: +.IP +http://zlib.net/ +.LP +The data format used by the zlib library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) +.br +http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) +.br +http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) +.LP +Mark Nelson wrote an article about +.I zlib +for the Jan. 1997 issue of Dr. Dobb's Journal; +a copy of the article is available at: +.IP +http://marknelson.us/1997/01/01/zlib-engine/ +.SH "REPORTING PROBLEMS" +Before reporting a problem, +please check the +.I zlib +web site to verify that you have the latest version of +.IR zlib ; +otherwise, +obtain the latest version and see if the problem still exists. +Please read the +.I zlib +FAQ at: +.IP +http://zlib.net/zlib_faq.html +.LP +before asking for help. +Send questions and/or comments to zlib@gzip.org, +or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). +.SH AUTHORS +Version 1.2.8 +Copyright (C) 1995-2013 Jean-loup Gailly (jloup@gzip.org) +and Mark Adler (madler@alumni.caltech.edu). +.LP +This software is provided "as-is," +without any express or implied warranty. +In no event will the authors be held liable for any damages +arising from the use of this software. +See the distribution directory with respect to requirements +governing redistribution. +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/libz/zlib.h b/libz/zlib.h new file mode 100644 index 000000000..3e0c7672a --- /dev/null +++ b/libz/zlib.h @@ -0,0 +1,1768 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.8, April 28th, 2013 + + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.8" +#define ZLIB_VERNUM 0x1280 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 8 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). Then deflate is guaranteed to + return Z_STREAM_END. If not enough output space is provided, deflate will + not return Z_STREAM_END, and it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + producted so far. The CRC-32 is checked against the gzip trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similary, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, + z_const unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) 'T' will + request transparent writing or appending with no compression and not using + the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + +#endif /* !Z_SOLO */ + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); +ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); +ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/libz/zlib.map b/libz/zlib.map new file mode 100644 index 000000000..55c6647eb --- /dev/null +++ b/libz/zlib.map @@ -0,0 +1,83 @@ +ZLIB_1.2.0 { + global: + compressBound; + deflateBound; + inflateBack; + inflateBackEnd; + inflateBackInit_; + inflateCopy; + local: + deflate_copyright; + inflate_copyright; + inflate_fast; + inflate_table; + zcalloc; + zcfree; + z_errmsg; + gz_error; + gz_intmax; + _*; +}; + +ZLIB_1.2.0.2 { + gzclearerr; + gzungetc; + zlibCompileFlags; +} ZLIB_1.2.0; + +ZLIB_1.2.0.8 { + deflatePrime; +} ZLIB_1.2.0.2; + +ZLIB_1.2.2 { + adler32_combine; + crc32_combine; + deflateSetHeader; + inflateGetHeader; +} ZLIB_1.2.0.8; + +ZLIB_1.2.2.3 { + deflateTune; + gzdirect; +} ZLIB_1.2.2; + +ZLIB_1.2.2.4 { + inflatePrime; +} ZLIB_1.2.2.3; + +ZLIB_1.2.3.3 { + adler32_combine64; + crc32_combine64; + gzopen64; + gzseek64; + gztell64; + inflateUndermine; +} ZLIB_1.2.2.4; + +ZLIB_1.2.3.4 { + inflateReset2; + inflateMark; +} ZLIB_1.2.3.3; + +ZLIB_1.2.3.5 { + gzbuffer; + gzoffset; + gzoffset64; + gzclose_r; + gzclose_w; +} ZLIB_1.2.3.4; + +ZLIB_1.2.5.1 { + deflatePending; +} ZLIB_1.2.3.5; + +ZLIB_1.2.5.2 { + deflateResetKeep; + gzgetc_; + inflateResetKeep; +} ZLIB_1.2.5.1; + +ZLIB_1.2.7.1 { + inflateGetDictionary; + gzvprintf; +} ZLIB_1.2.5.2; diff --git a/libz/zlib.pc.cmakein b/libz/zlib.pc.cmakein new file mode 100644 index 000000000..a5e642938 --- /dev/null +++ b/libz/zlib.pc.cmakein @@ -0,0 +1,13 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@INSTALL_LIB_DIR@ +sharedlibdir=@INSTALL_LIB_DIR@ +includedir=@INSTALL_INC_DIR@ + +Name: zlib +Description: zlib compression library +Version: @VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz +Cflags: -I${includedir} diff --git a/libz/zlib.pc.in b/libz/zlib.pc.in new file mode 100644 index 000000000..7e5acf9c7 --- /dev/null +++ b/libz/zlib.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +sharedlibdir=@sharedlibdir@ +includedir=@includedir@ + +Name: zlib +Description: zlib compression library +Version: @VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz +Cflags: -I${includedir} diff --git a/libz/zlib2ansi b/libz/zlib2ansi new file mode 100644 index 000000000..15e3e165f --- /dev/null +++ b/libz/zlib2ansi @@ -0,0 +1,152 @@ +#!/usr/bin/perl + +# Transform K&R C function definitions into ANSI equivalent. +# +# Author: Paul Marquess +# Version: 1.0 +# Date: 3 October 2006 + +# TODO +# +# Asumes no function pointer parameters. unless they are typedefed. +# Assumes no literal strings that look like function definitions +# Assumes functions start at the beginning of a line + +use strict; +use warnings; + +local $/; +$_ = <>; + +my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments + +my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ; +my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ; +my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ; + + +while (s/^ + ( # Start $1 + ( # Start $2 + .*? # Minimal eat content + ( ^ \w [\w\s\*]+ ) # $3 -- function name + \s* # optional whitespace + ) # $2 - Matched up to before parameter list + + \( \s* # Literal "(" + optional whitespace + ( [^\)]+ ) # $4 - one or more anythings except ")" + \s* \) # optional whitespace surrounding a Literal ")" + + ( (?: $dList )+ ) # $5 + + $sp ^ { # literal "{" at start of line + ) # Remember to $1 + //xsom + ) +{ + my $all = $1 ; + my $prefix = $2; + my $param_list = $4 ; + my $params = $5; + + StripComments($params); + StripComments($param_list); + $param_list =~ s/^\s+//; + $param_list =~ s/\s+$//; + + my $i = 0 ; + my %pList = map { $_ => $i++ } + split /\s*,\s*/, $param_list; + my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ; + + my @params = split /\s*;\s*/, $params; + my @outParams = (); + foreach my $p (@params) + { + if ($p =~ /,/) + { + my @bits = split /\s*,\s*/, $p; + my $first = shift @bits; + $first =~ s/^\s*//; + push @outParams, $first; + $first =~ /^(\w+\s*)/; + my $type = $1 ; + push @outParams, map { $type . $_ } @bits; + } + else + { + $p =~ s/^\s+//; + push @outParams, $p; + } + } + + + my %tmp = map { /$pMatch/; $_ => $pList{$1} } + @outParams ; + + @outParams = map { " $_" } + sort { $tmp{$a} <=> $tmp{$b} } + @outParams ; + + print $prefix ; + print "(\n" . join(",\n", @outParams) . ")\n"; + print "{" ; + +} + +# Output any trailing code. +print ; +exit 0; + + +sub StripComments +{ + + no warnings; + + # Strip C & C++ coments + # From the perlfaq + $_[0] =~ + + s{ + /\* ## Start of /* ... */ comment + [^*]*\*+ ## Non-* followed by 1-or-more *'s + ( + [^/*][^*]*\*+ + )* ## 0-or-more things which don't start with / + ## but do end with '*' + / ## End of /* ... */ comment + + | ## OR C++ Comment + // ## Start of C++ comment // + [^\n]* ## followed by 0-or-more non end of line characters + + | ## OR various things which aren't comments: + + ( + " ## Start of " ... " string + ( + \\. ## Escaped char + | ## OR + [^"\\] ## Non "\ + )* + " ## End of " ... " string + + | ## OR + + ' ## Start of ' ... ' string + ( + \\. ## Escaped char + | ## OR + [^'\\] ## Non '\ + )* + ' ## End of ' ... ' string + + | ## OR + + . ## Anything other char + [^/"'\\]* ## Chars which doesn't start a comment, string or escape + ) + }{$2}gxs; + +} diff --git a/libz/zutil.c b/libz/zutil.c new file mode 100644 index 000000000..23d2ebef0 --- /dev/null +++ b/libz/zutil.c @@ -0,0 +1,324 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" +#ifndef Z_SOLO +# include "gzguts.h" +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +z_const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifndef Z_SOLO + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ + +#endif /* !Z_SOLO */ diff --git a/libz/zutil.h b/libz/zutil.h new file mode 100644 index 000000000..24ab06b1c --- /dev/null +++ b/libz/zutil.h @@ -0,0 +1,253 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2013 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#ifdef HAVE_HIDDEN +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#if defined(STDC) && !defined(Z_SOLO) +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include +# endif +# include +# include +#endif + +#ifdef Z_SOLO + typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# ifndef Z_SOLO +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# if defined(M_I86) && !defined(Z_SOLO) +# include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# ifndef Z_SOLO +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) && !defined(MSDOS) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_WIN32) && \ + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(pyr) || defined(Z_SOLO) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +#ifndef Z_SOLO + voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); + void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +#endif + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +/* Reverse the bytes in a 32-bit value */ +#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +#endif /* ZUTIL_H */ diff --git a/mswin32/nmap.sln b/mswin32/nmap.sln index 41c3caa6d..75f8bfdf7 100644 --- a/mswin32/nmap.sln +++ b/mswin32/nmap.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 +# Visual Studio Express 2013 for Windows Desktop +VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nmap", "nmap.vcxproj", "{361719F0-AB42-4C93-9DE8-7D2144B96625}" ProjectSection(ProjectDependencies) = postProject @@ -28,6 +28,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblinear", "..\liblinear\l EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nmap-update", "..\nmap-update\nmap-update.vcxproj", "{BBF27339-C7B6-4F52-B742-897796C1F13B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libz", "..\libz\contrib\vstudio\vc11\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libssh2", "..\libssh2\win32\libssh2.vcxproj", "{ED957342-E43B-496E-92D9-4C76B525BDF5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -95,6 +99,18 @@ Global {BBF27339-C7B6-4F52-B742-897796C1F13B}.Ncat Static|Win32.Build.0 = Release|Win32 {BBF27339-C7B6-4F52-B742-897796C1F13B}.Release|Win32.ActiveCfg = Release|Win32 {BBF27339-C7B6-4F52-B742-897796C1F13B}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Ncat Static|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Ncat Static|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.Debug|Win32.ActiveCfg = Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.Debug|Win32.Build.0 = Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.Ncat Static|Win32.ActiveCfg = Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.Ncat Static|Win32.Build.0 = Debug|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.Release|Win32.ActiveCfg = Release|Win32 + {ED957342-E43B-496E-92D9-4C76B525BDF5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/mswin32/nmap.vcxproj b/mswin32/nmap.vcxproj index 34443084d..33957f7e7 100644 --- a/mswin32/nmap.vcxproj +++ b/mswin32/nmap.vcxproj @@ -54,7 +54,9 @@ Disabled - .;..;..\liblua;..\nbase;..\libpcre;..\nsock\include;pcap-include;..\libdnet-stripped\include;..\..\nmap-mswin32-aux\OpenSSL\include;..\liblinear;%(AdditionalIncludeDirectories) + ..\libssh2\include;.;..;..\liblua;..\nbase;..\libpcre;..\nsock\include;pcap-include;..\libdnet-stripped\include;..\..\nmap-mswin32-aux\OpenSSL\include;..\liblinear;%(AdditionalIncludeDirectories) + WIN32;_CONSOLE;%(PreprocessorDefinitions) + ..\libssh2\include;.;..;..\liblua;..\nbase;..\libpcre;..\nsock\include;pcap-include;..\libdnet-stripped\include;..\..\nmap-mswin32-aux\OpenSSL\include;..\liblinear;%(AdditionalIncludeDirectories) WIN32;_CONSOLE;BPF_MAJOR_VERSION;%(PreprocessorDefinitions) false false @@ -74,10 +76,10 @@ false - liblua.lib;nsock.lib;libpcre.lib;nbase.lib;libdnet-stripped.lib;liblinear.lib;ws2_32.lib;IPHlpAPI.Lib;wpcap.lib;packet.lib;advapi32.lib;libeay32.lib;ssleay32.lib;shell32.lib;libnetutil.lib + liblua.lib;nsock.lib;libpcre.lib;nbase.lib;libdnet-stripped.lib;liblinear.lib;ws2_32.lib;IPHlpAPI.Lib;wpcap.lib;packet.lib;advapi32.lib;libeay32.lib;ssleay32.lib;shell32.lib;libnetutil.lib;libssh2.lib .\Debug\nmap.exe true - lib;..\liblua;..\libpcre;..\nsock;..\nbase;..\libdnet-stripped;../libnetutil;..\..\nmap-mswin32-aux\OpenSSL\lib;..\liblinear;%(AdditionalLibraryDirectories) + ..\libssh2\win32\Debug_dll;..\liblua;lib;..\libpcre;..\nsock;..\nbase;..\libdnet-stripped;..\libnetutil;..\..\nmap-mswin32-aux\OpenSSL\lib;..\liblinear;%(AdditionalLibraryDirectories) %(IgnoreSpecificDefaultLibraries) packet.dll;wpcap.dll;iphlpapi.dll;%(DelayLoadDLLs) true @@ -89,8 +91,12 @@ MachineX86 - xcopy "$(SolutionDir)..\scripts" ".\$(Configuration)\scripts\" /e /y && xcopy "$(SolutionDir)..\nselib\*.lua" "$(SolutionDir)\$(Configuration)\nselib\" /y && xcopy /s /e "$(SolutionDir)..\nselib\data\*.*" "$(SolutionDir)\$(Configuration)\nselib\data\" /y && xcopy "$(SolutionDir)\..\..\nmap-mswin32-aux\OpenSSL\bin\*.dll" "$(SolutionDir)\$(Configuration)\" /y && xcopy "$(SolutionDir)..\nse_main.lua" "$(SolutionDir)\$(Configuration)\" /y + xcopy "$(SolutionDir)..\scripts" ".\$(Configuration)\scripts\" /e /y && xcopy "$(SolutionDir)..\nselib\*.lua" "$(SolutionDir)\$(Configuration)\nselib\" /y && xcopy /s /e "$(SolutionDir)..\nselib\data\*.*" "$(SolutionDir)\$(Configuration)\nselib\data\" /y && xcopy "$(SolutionDir)\..\..\nmap-mswin32-aux\OpenSSL\bin\*.dll" "$(SolutionDir)\$(Configuration)\" /y && xcopy "$(SolutionDir)..\nse_main.lua" "$(SolutionDir)\$(Configuration)\" /y +xcopy /y /d "$(ProjectDir)..\libssh2\win32\$(Configuration)_dll\*.dll" "$(ProjectDir)$(OutDir)" + + $(IntDir)%(Filename).res + @@ -101,7 +107,7 @@ MaxSpeed OnlyExplicitInline - .;..;..\liblua;..\nbase;..\libpcre;..\nsock\include;pcap-include;..\libdnet-stripped\include;..\..\nmap-mswin32-aux\OpenSSL\include;..\liblinear;%(AdditionalIncludeDirectories) + ..\libssh2\include;.;..;..\liblua;..\nbase;..\libpcre;..\nsock\include;pcap-include;..\libdnet-stripped\include;..\..\nmap-mswin32-aux\OpenSSL\include;..\liblinear;%(AdditionalIncludeDirectories) WIN32;_CONSOLE;BPF_MAJOR_VERSION;%(PreprocessorDefinitions) true true @@ -115,10 +121,10 @@ CompileAsCpp - liblua.lib;nsock.lib;libpcre.lib;nbase.lib;libdnet-stripped.lib;liblinear.lib;ws2_32.lib;IPHlpAPI.Lib;wpcap.lib;packet.lib;advapi32.lib;libeay32.lib;ssleay32.lib;shell32.lib;libnetutil.lib + liblua.lib;nsock.lib;libpcre.lib;nbase.lib;libdnet-stripped.lib;libssh2.lib;liblinear.lib;ws2_32.lib;IPHlpAPI.Lib;wpcap.lib;packet.lib;advapi32.lib;libeay32.lib;ssleay32.lib;shell32.lib;libnetutil.lib .\Release/nmap.exe true - lib;..\liblua;..\libpcre;..\nsock;..\nbase;..\libdnet-stripped;../libnetutil;..\..\nmap-mswin32-aux\OpenSSL\lib;..\liblinear;%(AdditionalLibraryDirectories) + ..\libssh2\win32\Release_dll;lib;..\liblua;..\libpcre;..\nsock;..\nbase;..\libdnet-stripped;../libnetutil;..\..\nmap-mswin32-aux\OpenSSL\lib;..\liblinear;%(AdditionalLibraryDirectories) %(IgnoreSpecificDefaultLibraries) packet.dll;wpcap.dll;iphlpapi.dll;%(DelayLoadDLLs) .\Release/nmap.pdb @@ -129,7 +135,8 @@ /LTCG %(AdditionalOptions) - xcopy "$(SolutionDir)..\scripts" ".\$(Configuration)\scripts\" /e /y && xcopy "$(SolutionDir)..\nselib\*.lua" "$(SolutionDir)\$(Configuration)\nselib\" /y && xcopy /s /e "$(SolutionDir)..\nselib\data\*.*" "$(SolutionDir)\$(Configuration)\nselib\data\" /y && xcopy "$(SolutionDir)\..\..\nmap-mswin32-aux\OpenSSL\bin\*.dll" "$(SolutionDir)\$(Configuration)\" /y && xcopy "$(SolutionDir)..\nse_main.lua" "$(SolutionDir)\$(Configuration)\" /y + xcopy "$(SolutionDir)..\scripts" ".\$(Configuration)\scripts\" /e /y && xcopy "$(SolutionDir)..\nselib\*.lua" "$(SolutionDir)\$(Configuration)\nselib\" /y && xcopy /s /e "$(SolutionDir)..\nselib\data\*.*" "$(SolutionDir)\$(Configuration)\nselib\data\" /y && xcopy "$(SolutionDir)\..\..\nmap-mswin32-aux\OpenSSL\bin\*.dll" "$(SolutionDir)\$(Configuration)\" /y && xcopy "$(SolutionDir)..\nse_main.lua" "$(SolutionDir)\$(Configuration)\" /y +xcopy /y /d "$(ProjectDir)..\libssh2\win32\$(Configuration)_dll\*.dll" "$(ProjectDir)$(OutDir)" @@ -149,6 +156,7 @@ + @@ -203,6 +211,7 @@ + @@ -330,6 +339,14 @@ {5de86c7a-de72-4265-8807-4ca38f94f22a} false + + {ed957342-e43b-496e-92d9-4c76b525bdf5} + false + false + false + true + false + {b630c8f7-3138-43e8-89ed-78742fa2ac5f} false diff --git a/nbase/nbase_winconfig.h b/nbase/nbase_winconfig.h index 955f4b9d5..a9d9ebd76 100644 --- a/nbase/nbase_winconfig.h +++ b/nbase/nbase_winconfig.h @@ -219,6 +219,8 @@ typedef signed __int64 int64_t; #define HAVE_OPENSSL 1 #define HAVE_SSL_SET_TLSEXT_HOST_NAME 1 +#define HAVE_LIBSSH2 1 +#define HAVE_LIBZ_V 1 /* Apparently __func__ isn't yet supported */ #define __func__ __FUNCTION__ diff --git a/nmap.cc b/nmap.cc index 209c4f076..877fc99fa 100644 --- a/nmap.cc +++ b/nmap.cc @@ -181,6 +181,14 @@ #include #endif +#if HAVE_LIBSSH2 +#include "libssh2/libssh2v.h" +#endif + +#if HAVE_LIBZ_V +#include "libz/libzv.h" +#endif + /* To get the version number only. */ #ifdef WIN32 #include "libdnet-stripped/include/dnet_winconfig.h" @@ -2834,6 +2842,18 @@ static void display_nmap_version() { without.push_back("openssl"); #endif +#if HAVE_LIBSSH2 + with.push_back(std::string("libssh2-") + get_word_or_quote(LIBSSH2_VERSION_TEXT, 1)); +#else + without.push_back("libssh2"); +#endif + +#if HAVE_LIBZ_V + with.push_back(std::string("libz-") + get_word_or_quote(LIBZ_VERSION_TEXT, 1)); +#else + without.push_back("libz"); +#endif + #ifdef PCRE_INCLUDED with.push_back(std::string("nmap-libpcre-") + get_word_or_quote(pcre_version(), 0)); #else diff --git a/nmap_config.h.in b/nmap_config.h.in index c141134c2..cb53595ad 100644 --- a/nmap_config.h.in +++ b/nmap_config.h.in @@ -196,6 +196,10 @@ #undef HAVE_OPENSSL +#undef HAVE_LIBSSH2 + +#undef HAVE_LIBZ_V + #undef HAVE_OPENSSL_EC #undef STUPID_SOLARIS_CHECKSUM_BUG diff --git a/nmap_winconfig.h b/nmap_winconfig.h index bb59dfad9..912d790f5 100644 --- a/nmap_winconfig.h +++ b/nmap_winconfig.h @@ -144,6 +144,8 @@ #define HAVE_OPENSSL 1 #define HAVE_SSL_SET_TLSEXT_HOST_NAME 1 +/* Since MSVC 2010, stdint.h is included as part of C99 compatibility */ +#define HAVE_STDINT_H 1 #define LUA_INCLUDED 1 #undef PCAP_INCLUDED diff --git a/nse_libssh2.cc b/nse_libssh2.cc new file mode 100644 index 000000000..bf721b663 --- /dev/null +++ b/nse_libssh2.cc @@ -0,0 +1,950 @@ +/* +* Binding for the libssh2 library. Note that there is not a one-to-one correspondance +* between functions in libssh2 and the binding. +* Currently, during the ssh2 handshake, a call to nsock.recieve may result in an EOF +* error. This appears to only occur when stressing the ssh server (ie during a brute +* force attempt) or while behind a restrictive firewall/IDS. +* by Devin Bjelland +*/ + +extern "C" { +#include "lua.h" +#include "lauxlib.h" +#include "libssh2.h" +} + +#include "nse_debug.h" +#include "nse_nsock.h" +#include "nse_utility.h" + +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#endif + + +enum { + SSH2_UDATA = lua_upvalueindex(1) +}; + +#ifdef WIN32 +struct ssh_userdata { + SOCKET sp[2]; + LIBSSH2_SESSION *session; +}; +#else +struct ssh_userdata { + int sp[2]; + LIBSSH2_SESSION *session; +}; +#endif + + +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf c99_snprintf +#define vsnprintf c99_vsnprintf + +__inline int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) { + int count = -1; + + if (size != 0) + count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +__inline int c99_snprintf(char *outBuf, size_t size, const char *format, ...) { + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(outBuf, size, format, ap); + va_end(ap); + + return count; +} +#endif + +#ifdef WIN32 +/* +* make_socketpair: +* If make_overlapped is nonzero, both sockets created will be usable for +* "overlapped" operations via WSASend etc. If make_overlapped is zero, +* socks[0] (only) will be usable with regular ReadFile etc., and thus +* suitable for use as stdin or stdout of a child process. Note that the +* sockets must be closed with closesocket() regardless. +*/ + +int make_socketpair (SOCKET socks[2], int make_overlapped) { + union { + struct sockaddr_in inaddr; + struct sockaddr addr; + } a; + SOCKET listener; + int e; + socklen_t addrlen = sizeof(a.inaddr); + DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0); + int reuse = 1; + + if (socks == 0) { + WSASetLastError(WSAEINVAL); + return SOCKET_ERROR; + } + socks[0] = socks[1] = -1; + + listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listener == -1) + return SOCKET_ERROR; + + memset(&a, 0, sizeof(a)); + a.inaddr.sin_family = AF_INET; + a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + a.inaddr.sin_port = 0; + + for (;;) { + if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, + (char*)&reuse, (socklen_t) sizeof(reuse)) == -1) + break; + if (bind(listener, &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) + break; + + memset(&a, 0, sizeof(a)); + if (getsockname(listener, &a.addr, &addrlen) == SOCKET_ERROR) + break; + // win32 getsockname may only set the port number, p=0.0005. + // ( http://msdn.microsoft.com/library/ms738543.aspx ): + a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + a.inaddr.sin_family = AF_INET; + + if (listen(listener, 1) == SOCKET_ERROR) + break; + + socks[0] = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, flags); + if (socks[0] == -1) + break; + if (connect(socks[0], &a.addr, sizeof(a.inaddr)) == SOCKET_ERROR) + break; + + socks[1] = accept(listener, NULL, NULL); + if (socks[1] == -1) + break; + + closesocket(listener); + return 0; + } + + e = WSAGetLastError(); + closesocket(listener); + closesocket(socks[0]); + closesocket(socks[1]); + WSASetLastError(e); + socks[0] = socks[1] = -1; + //return SOCKET_ERROR; + + return -1; +} +#else +int make_socketpair (int socks[2], int dummy) { + if (socks == 0) { + errno = EINVAL; + return -1; + } + + dummy = socketpair(AF_UNIX, SOCK_STREAM, 0, socks); + + if (dummy) { + socks[0] = socks[1] = -1; + } + + return dummy; +} +#endif + + +static int ssh_error (lua_State *L, LIBSSH2_SESSION *session, const char *msg) { + char *errmsg; + libssh2_session_last_error(session, &errmsg, NULL, 0); + + return nseU_safeerror(L, "%s: %s", msg, errmsg); +} + +static int finish_send (lua_State *L, int status, lua_KContext ctx) { + if (lua_toboolean(L, -2)) + return 0; + else + return lua_error(L); /* uses idx 6 */ +} + +static int finish_read (lua_State *L, int status, lua_KContext ctx) { + int rc; + struct ssh_userdata *sshu = NULL; + + sshu = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + + if (lua_toboolean(L, -2)) { + size_t n = 0; + size_t l = 0; + lua_getuservalue(L, 1); + lua_getfield(L, -1, "sp_buff"); + lua_pushvalue(L, 3); + lua_concat(L, 2); + const char *data = lua_tolstring(L, -1, &l); + lua_pushliteral(L, ""); + lua_setfield(L, 4, "sp_buff"); + + while (n < l) { +#ifdef WIN32 + rc = send(sshu->sp[1], data + n, l - n, 0); +#else + rc = write(sshu->sp[1], data + n, l - n); +#endif + if (rc == -1 && errno != EAGAIN) { + luaL_error(L, "Writing to socket pair: %s", strerror(errno)); + } + else if (rc == -1 && errno == EAGAIN) { + lua_pushlstring(L, data + n, l - n); + lua_setfield(L, 4, "sp_buff"); + break; + } + else { + n += rc; + } + } + return 0; + } + else { + return lua_error(L); /* uses idx 6 */ + } +} + +static int filter (lua_State *L) { + int rc; + char data[4096]; + struct ssh_userdata *sshu = NULL; + + sshu = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + + lua_getuservalue(L, 1); + lua_getfield(L, -1, "sock"); + lua_replace(L, -2); + +#ifdef WIN32 + rc = recv(sshu->sp[1], data, sizeof(data), 0); + + if (WSAGetLastError() == WSAEWOULDBLOCK) + rc = 0; +#else + rc = read(sshu->sp[1], data, sizeof(data)); +#endif + + if (rc > 0) { + //write data to nsock socket + lua_getfield(L, -1, "send"); + lua_insert(L, -2); /* swap */ + lua_pushlstring(L, data, rc); + + assert(lua_status(L) == LUA_OK); + lua_callk(L, 2, 2, 0, finish_send); + + return finish_send(L,0,0); + } + else if (rc == -1 && errno != EAGAIN) + return luaL_error(L, "%s", strerror(errno)); + + lua_getfield(L, -1, "receive"); + lua_insert(L, -2); /* swap */ + + assert(lua_status(L) == LUA_OK); + lua_callk(L, 1, 2, 0, finish_read); + + return finish_read(L, 0, 0); +} + +static int do_session_handshake (lua_State *L, int status, lua_KContext ctx) { + int rc; + struct ssh_userdata *sshu = NULL; + + assert(lua_gettop(L) == 4); + sshu = (struct ssh_userdata *) nseU_checkudata(L, 3, SSH2_UDATA, "ssh2"); + + while ((rc = libssh2_session_handshake(sshu->session, sshu->sp[0])) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 3, "filter"); + lua_pushvalue(L, 3); + + assert(lua_status(L) == LUA_OK); + lua_callk(L, 1, 0, 0, do_session_handshake); + } + + if (rc) { + libssh2_session_free(sshu->session); + return luaL_error(L, "Unable to complete libssh2 handshake."); + } + + // lua_pushvalue(L, 3); + lua_settop(L, 3); + + return 1; +} + +static int finish_session_open (lua_State *L, int status, lua_KContext ctx) { + assert(lua_gettop(L) == 6); + if (lua_toboolean(L, -2)) { + lua_pop(L, 2); + return do_session_handshake(L,0,0); + } + else { + struct ssh_userdata *state = NULL; + + state = (struct ssh_userdata *) nseU_checkudata(L, 3, SSH2_UDATA, "ssh2"); + if (state->session != NULL) { + libssh2_session_free(state->session); + state->session = NULL; + } + return lua_error(L); + } +} + +/* +* Creates libssh2 session, connects to hostname:port and tries to perform a +* ssh handshake on socket. Returns ssh_state on success, nil on failure. +* +* session_open(hostname, port) +*/ +static int l_session_open (lua_State *L) { + int rc; + ssh_userdata *state = NULL; + + luaL_checkinteger(L, 2); + lua_settop(L, 2); + + state = (ssh_userdata *)lua_newuserdata(L, sizeof(ssh_userdata)); /* index 3 */ + + assert(lua_gettop(L) == 3); + state->session = NULL; + state->sp[0] = -1; + state->sp[1] = -1; + lua_pushvalue(L, lua_upvalueindex(1)); /* metatable */ + lua_setmetatable(L, 3); + + lua_newtable(L); + lua_setuservalue(L, 3); + lua_getuservalue(L, 3); /* index 4 - a table associated with userdata*/ + assert(lua_gettop(L) == 4); + + state->session = libssh2_session_init(); + + if (state->session == NULL) { + // A session could not be created because of memory limit + return nseU_safeerror(L, "trying to initiate session"); + } + + libssh2_session_set_blocking(state->session, 0); + + if (make_socketpair(state->sp, 1) == -1) + return nseU_safeerror(L, "trying to create socketpair"); + +#ifdef WIN32 + unsigned long s_mode = 1; // non-blocking + + rc = ioctlsocket(state->sp[1], FIONBIO, (unsigned long *)&s_mode); + if (rc != NO_ERROR) + return nseU_safeerror(L, "%s", strerror(errno)); +#else + // get file descriptor flags + rc = fcntl(state->sp[1], F_GETFD); + if (rc == -1) + return nseU_safeerror(L, "%s", strerror(errno)); + + // add non-blocking flag and update file descriptor flags + rc |= O_NONBLOCK; + rc = fcntl(state->sp[1], F_SETFL, rc); + if (rc == -1) + return nseU_safeerror(L, "%s", strerror(errno)); +#endif + + lua_getglobal(L, "nmap"); + lua_getfield(L, -1, "new_socket"); + lua_replace(L, -2); + lua_call(L, 0, 1); + lua_setfield(L, 4, "sock"); + lua_pushliteral(L, ""); + lua_setfield(L, 4, "sp_buff"); + assert(lua_gettop(L) == 4); + + lua_getfield(L, 4, "sock"); + lua_getfield(L, -1, "connect"); + lua_insert(L, -2); /* swap */ + lua_pushvalue(L, 1); + lua_pushvalue(L, 2); + lua_callk(L, 3, 2, 3, finish_session_open); + return finish_session_open(L,0,0); +} + +/* +* Returns the SHA1 or MD5 hostkey hash of provided session or nil if it is not available +*/ +static int l_hostkey_hash (lua_State *L) { + luaL_Buffer B; + static int hash_option[] = { LIBSSH2_HOSTKEY_HASH_MD5, LIBSSH2_HOSTKEY_HASH_SHA1 }; + static int hash_length[] = { 16, 20 }; + static const char *hashes[] = { "md5", "sha1", NULL }; + int type = luaL_checkoption(L, 2, "sha1", hashes); + struct ssh_userdata *state = NULL; + const unsigned char *hash = NULL; + + state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + hash = (const unsigned char *) libssh2_hostkey_hash(state->session, hash_option[type]); + + if (hash == NULL) + return nseU_safeerror(L, "could not get hostkey hash"); + + luaL_buffinit(L, &B); + for (int i = 0; i < hash_length[type]; i++) { + char byte[3]; /* with space for NULL */ + snprintf(byte, sizeof(byte), "%02X", (unsigned int)hash[i]); + if (i) + luaL_addchar(&B, ':'); + luaL_addlstring(&B, byte, 2); + } + luaL_pushresult(&B); + + return 1; +} + +static int l_set_timeout(lua_State *L) { + long timeout = luaL_checkinteger(L, 2); + struct ssh_userdata *state = NULL; + state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + + libssh2_session_set_timeout(state->session, timeout); + + return 0; +} + +static int userauth_list (lua_State *L, int status, lua_KContext ctx) { + char *auth_list = NULL; + struct ssh_userdata *state = NULL; + const char *username = luaL_checkstring(L, 2); + + state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + assert(state->session != NULL); + + while ((auth_list = libssh2_userauth_list(state->session, username, lua_rawlen(L, 2))) == NULL + && libssh2_session_last_errno(state->session) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + + assert(lua_status(L) == LUA_OK); + lua_callk(L, 1, 0, 0, userauth_list); + } + + if (auth_list) { + const char *auth = strtok(auth_list, ","); + lua_newtable(L); + do { + lua_pushstring(L, auth); + lua_rawseti(L, -2, lua_rawlen(L, -2) + 1); + } + while ((auth = strtok(NULL, ","))); + + //libssh2_free(state->session, (void *)auth_list); + } + else if (libssh2_userauth_authenticated(state->session)) { + lua_pushliteral(L, "none_auth"); + } + else { + return ssh_error(L, state->session, "userauth_list"); + } + + return 1; +} + +/* +* Returns list of supported authenication methods +*/ +static int l_userauth_list (lua_State *L) { + return userauth_list(L, 0, 0); +} + +static int userauth_publickey (lua_State *L, int status, lua_KContext ctx) { + int rc; + const char *username, *private_key_file, *passphrase, *public_key_file; + struct ssh_userdata *state = NULL; + state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + + username = luaL_checkstring(L, 2); + private_key_file = luaL_checkstring(L, 3); + + if (lua_isstring(L, 4)) + passphrase = lua_tostring(L, 4); + else + passphrase = NULL; + + if (lua_isstring(L, 5)) + public_key_file = lua_tostring(L, 5); + else + public_key_file = NULL; + + while ((rc = libssh2_userauth_publickey_fromfile( + state->session, username, public_key_file, private_key_file, passphrase + )) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + + assert(lua_status(L) == LUA_OK); + lua_callk(L, 1, 0, 0, userauth_publickey); + } + + if (rc == 0) + lua_pushboolean(L, 1); + else + lua_pushboolean(L, 0); + + return 1; +} + +static int l_userauth_publickey (lua_State *L) { + return userauth_publickey(L, 0, 0); +} + +static int l_read_publickey (lua_State *L) { + FILE *fd; + char c; + const char* publickeyfile = luaL_checkstring(L, 1); + luaL_Buffer publickey_data; + + fd = fopen(publickeyfile, "r"); + if (!fd) + return luaL_error(L, "Error reading file"); + + luaL_buffinit(L, &publickey_data); + while (fread(&c, 1, 1, fd) && c!= '\r' && c != '\n' && c != ' ') { + continue; + } + while (fread(&c, 1, 1, fd) && c!= '\r' && c != '\n' && c != ' ') { + luaL_addchar(&publickey_data, c); + } + fclose(fd); + + lua_getglobal(L, "require"); + lua_pushstring(L, "base64"); + lua_call(L, 1, 1); + lua_getfield(L, -1, "dec"); + + luaL_pushresult(&publickey_data); + lua_call(L, 1, 1); + + return 1; +} + +static int publickey_canauth_cb (LIBSSH2_SESSION *session, unsigned char **sig, + size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract) { + return 0; +} + +static int publickey_canauth (lua_State *L, int status, lua_KContext ctx) { + int rc; + int errlen; + char *errmsg; + const char *username; + unsigned const char *publickey_data; + size_t len = 0; + struct ssh_userdata *state; + + state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + username = luaL_checkstring(L, 2); + + if (lua_isstring(L, 3)) + publickey_data = (unsigned const char*)lua_tolstring(L, 3, &len); + else + return luaL_error(L, "Invalid public key"); + + while ((rc = libssh2_userauth_publickey(state->session, + username, publickey_data, len, &publickey_canauth_cb, NULL)) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + + assert(lua_status(L) == LUA_OK); + lua_callk(L, 1, 0, 0, publickey_canauth); + } + + libssh2_session_last_error(state->session, &errmsg, &errlen, 0); + + if (rc == LIBSSH2_ERROR_ALLOC || rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED) + lua_pushboolean(L, 1); //Username/PublicKey combination invalid + else if (rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED) + lua_pushboolean(L, 0); + else + return luaL_error(L, "Invalid Publickey"); + + return 1; +} + +static int l_publickey_canauth (lua_State *L) { + return publickey_canauth(L, 0, 0); +} + +/* +* Attempts to authenticate session with provided username and password +* returns true on success and false otherwise +* +* userauth_password(state, username, password) +*/ +static int userauth_password (lua_State *L, int status, lua_KContext ctx) { + int rc; + const char *username, *password; + struct ssh_userdata *state; + + state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + username = luaL_checkstring(L, 2); + password = luaL_checkstring(L, 3); + + assert(state->session != NULL); + while ((rc = libssh2_userauth_password(state->session, + username, password)) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + + assert(lua_status(L) == LUA_OK); + lua_callk(L, 1, 0, 0, userauth_password); + } + + if (rc == 0) + lua_pushboolean(L, 1); + else + lua_pushboolean(L, 0); + + return 1; +} + +static int l_userauth_password (lua_State *L) { + return userauth_password(L, 0, 0); +} + +static int session_close (lua_State *L, int status, lua_KContext ctx) { + int rc; + struct ssh_userdata *state; + + state = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + + if (state->session != NULL) { + while ((rc = libssh2_session_disconnect( + state->session, "Normal Shutdown")) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + + assert(lua_status(L) == LUA_OK); + lua_callk(L, 1, 0, 0, session_close); + } + + if (rc < 0) + return luaL_error(L, "unable to disconnect session"); + + if (libssh2_session_free(state->session) < 0) + return luaL_error(L, "unable to free session"); + + state->session = NULL; + } + + return 0; +} + +static int l_session_close (lua_State *L) { + return session_close(L, 0, 0); +} + +static int channel_read (lua_State *L, int status, lua_KContext ctx) { + int rc; + char buf[2048]; + size_t buflen = 2048; + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **) lua_touserdata(L, 2); + + while ((rc = libssh2_channel_read(*channel, buf, buflen)) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + lua_callk(L, 1, 0, 0, channel_read); + } + + if (rc > 0) { + lua_pushlstring(L, buf, rc); + return 1; + } + else if (rc < 0) + return luaL_error(L, "Reading from channel"); + + lua_pushnil(L); + + return 1; +} + +static int l_channel_read (lua_State *L) { + return channel_read(L, 0, 0); +} + +static int l_channel_read_stderr(lua_State *L) { + int rc; + char buf[2048]; + size_t buflen = 2048; + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **) lua_touserdata(L, 2); + + while ((rc = libssh2_channel_read_stderr(*channel, buf, buflen)) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + lua_callk(L, 1, 0, 0, channel_read); + } + + if (rc > 0) { + lua_pushlstring(L, buf, rc); + return 1; + } + else if (rc < 0) + return luaL_error(L, "Reading from channel"); + + lua_pushnil(L); + return 1; +} + +static int channel_write (lua_State *L, int status, lua_KContext ctx) { + int rc; + const char *buf; + size_t buflen = 0; + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **) lua_touserdata(L, 2); + + if (lua_isstring(L, 3)) + buf = lua_tolstring(L, 3, &buflen); + else + return luaL_error(L, "Invalid buffer"); + + while ((rc = libssh2_channel_write(*channel, buf, buflen)) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + lua_callk(L, 1, 0, 0, channel_write); + } + + if (rc < 0) + return luaL_error(L, "Writing to channel"); + + lua_pushinteger(L, rc); + return 1; +} + +static int l_channel_write (lua_State *L) { + return channel_write(L, 0, 0); +} + +static int channel_exec (lua_State *L, int status, lua_KContext ctx) { + int rc; + // ssh_userdata *state = (ssh_userdata *)lua_touserdata(L, 1); + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **) lua_touserdata(L, 2); + const char *cmd = luaL_checkstring(L, 3); + + while ((rc = libssh2_channel_exec(*channel, cmd)) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + lua_callk(L, 1, 0, 0, channel_exec); + } + if (rc != 0) + return luaL_error(L, "Error executing command"); + + return 0; +} + +static int l_channel_exec (lua_State *L) { + return channel_exec(L, 0, 0); +} + +static int l_channel_eof(lua_State *L) { + int result; + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **) lua_touserdata(L, 1); + + result = libssh2_channel_eof(*channel); + if (result >= 0) + lua_pushboolean(L, result); + else + return luaL_error(L, "Error checking for EOF"); + + return 1; +} + +static int channel_send_eof(lua_State *L, int status, lua_KContext ctx) { + int rc; + // ssh_userdata *state = (ssh_userdata *)lua_touserdata(L, 1); + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **) lua_touserdata(L, 2); + + while ((rc = libssh2_channel_send_eof(*channel)) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + lua_callk(L, 1, 0, 0, channel_send_eof); + } + if (rc != 0) + return luaL_error(L, "Error sending EOF"); + + return 0; +} + +static int l_channel_send_eof(lua_State *L) { + return channel_send_eof(L, 0, 0); +} + +static int setup_channel(lua_State *L, int status, lua_KContext ctx) { + int rc; + // ssh_userdata *state = (ssh_userdata *)lua_touserdata(L, 1); + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **) lua_touserdata(L, 2); + + while ((rc = libssh2_channel_request_pty(*channel, "vanilla")) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + lua_callk(L, 1, 0, 0, setup_channel); + } + if (rc != 0) + return luaL_error(L, "Requesting pty"); + + return 1; +} + +static int l_setup_channel (lua_State *L) { + return setup_channel(L, 0, 0); +} + +static int finish_open_channel (lua_State *L, int status, lua_KContext ctx) { + ssh_userdata *state = (ssh_userdata *)lua_touserdata(L, 1); + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **) lua_touserdata(L, 2); + + while ((*channel = libssh2_channel_open_session(state->session)) == NULL + && libssh2_session_last_errno(state->session) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + lua_callk(L, 1, 0, 0, finish_open_channel); + } + if (channel == NULL) + return luaL_error(L, "Opening channel"); + + return setup_channel(L, 0, 0); +} + +static int l_open_channel (lua_State *L) { + ssh_userdata *state = (ssh_userdata *)lua_touserdata(L, 1); + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **)lua_newuserdata(L, sizeof(LIBSSH2_CHANNEL *)); + + while ((*channel = libssh2_channel_open_session(state->session)) == NULL + && libssh2_session_last_errno(state->session) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + lua_callk(L, 1, 0, 0, finish_open_channel); + } + + return l_setup_channel(L); +} + +static int channel_close (lua_State *L, int status, lua_KContext ctx) { + int rc; + // ssh_userdata *state = (ssh_userdata *)lua_touserdata(L, 1); + LIBSSH2_CHANNEL **channel = (LIBSSH2_CHANNEL **) lua_touserdata(L, 2); + + while ((rc = libssh2_channel_close(*channel)) == LIBSSH2_ERROR_EAGAIN) { + luaL_getmetafield(L, 1, "filter"); + lua_pushvalue(L, 1); + lua_callk(L, 1, 0, 0, channel_close); + } + if (rc != 0) + return luaL_error(L, "Error closing channel");; + + return 0; +} + +static int l_channel_close (lua_State *L) { + return channel_close(L, 0, 0); +} + +static const struct luaL_Reg libssh2[] = { + { "session_open", l_session_open }, + { "hostkey_hash", l_hostkey_hash }, + { "set_timeout", l_set_timeout }, + { "userauth_list", l_userauth_list }, + { "userauth_publickey", l_userauth_publickey }, + { "read_publickey", l_read_publickey }, + { "publickey_canauth", l_publickey_canauth }, + { "userauth_password", l_userauth_password }, + { "session_close", l_session_close }, + { "open_channel", l_open_channel}, + { "channel_read", l_channel_read}, + { "channel_read_stderr", l_channel_read_stderr}, + { "channel_write", l_channel_write}, + { "channel_exec", l_channel_exec}, + { "channel_send_eof", l_channel_send_eof}, + { "channel_eof", l_channel_eof}, + { "channel_close", l_channel_close}, + { NULL, NULL } +}; + +static int gc (lua_State *L) { + struct ssh_userdata *sshu = NULL; + + sshu = (struct ssh_userdata *) nseU_checkudata(L, 1, SSH2_UDATA, "ssh2"); + if (!sshu) { return 0; } + if (sshu) { + // lua_pushvalue(L, lua_upvalueindex(1)); + // lua_getfield(L, -1, "session_close"); + // lua_insert(L, -2); /* swap */ + // lua_pcall(L, 1, 0, 0); /* if an error occurs, don't do anything */ + + if (sshu->session != NULL) { + if (libssh2_session_free(sshu->session) < 0) { + // Unable to free libssh2 session + } + sshu->session = NULL; + } + } + +#ifdef WIN32 + closesocket(sshu->sp[0]); + closesocket(sshu->sp[1]); +#else + close(sshu->sp[0]); + close(sshu->sp[1]); +#endif + + return 0; +} + +int luaopen_libssh2 (lua_State *L) { + lua_settop(L, 0); /* clear the stack */ + + luaL_newlibtable(L, libssh2); + + lua_newtable(L); /* ssh2 session metatable */ + lua_pushvalue(L, -1); + lua_pushcclosure(L, gc, 1); + lua_setfield(L, -2, "__gc"); + lua_pushvalue(L, -1); + lua_pushcclosure(L, filter, 1); + lua_setfield(L, -2, "filter"); + + luaL_setfuncs(L, libssh2, 1); + + static bool libssh2_initialized = false; + if (!libssh2_initialized && (libssh2_init(0) != 0)) + luaL_error(L, "unable to open libssh2"); + libssh2_initialized = true; + + return 1; +} diff --git a/nse_libssh2.h b/nse_libssh2.h new file mode 100644 index 000000000..a749fa5e0 --- /dev/null +++ b/nse_libssh2.h @@ -0,0 +1,8 @@ +#ifndef LIBSSH2 + +#define LIBSSH2 +#define LIBSSH2LIBNAME "libssh2" + +int luaopen_libssh2 (lua_State *L); + +#endif diff --git a/nse_main.cc b/nse_main.cc index 1125589f7..d3855b6a2 100644 --- a/nse_main.cc +++ b/nse_main.cc @@ -18,6 +18,7 @@ #include "nse_openssl.h" #include "nse_debug.h" #include "nse_lpeg.h" +#include "nse_libssh2.h" #include @@ -545,6 +546,9 @@ static void set_nmap_libraries (lua_State *L) {NSE_NMAPLIBNAME, luaopen_nmap}, {LFSLIBNAME, luaopen_lfs}, {LPEGLIBNAME, luaopen_lpeg}, +#ifdef HAVE_LIBSSH2 + {LIBSSH2LIBNAME, luaopen_libssh2}, +#endif #ifdef HAVE_OPENSSL {OPENSSLLIBNAME, luaopen_openssl}, #endif diff --git a/nse_utility.h b/nse_utility.h index f8a7c7a61..98bc5147d 100644 --- a/nse_utility.h +++ b/nse_utility.h @@ -6,7 +6,11 @@ class Target; #ifdef HAVE_CONFIG_H #include "nmap_config.h" -#endif +#else +#ifdef WIN32 +#include "nmap_winconfig.h" +#endif /* WIN32 */ +#endif /* HAVE_CONFIG_H */ #if HAVE_STDINT_H #include diff --git a/nselib/brute.lua b/nselib/brute.lua index 6f3054db7..8db710043 100644 --- a/nselib/brute.lua +++ b/nselib/brute.lua @@ -698,8 +698,17 @@ Engine = { repeat local driver = self.driver:new(self.host, self.port, self.driver_options) + status, response = driver:connect() + -- Temporary workaround. Did not connect sucessfully + -- due to stressed server + if not status and response:isReduce() then + local ret_creds = {} + ret_creds.connect_phase = true + return false, response, ret_creds + end + -- Did we successfully connect? if status then if not username and not password then @@ -833,11 +842,13 @@ Engine = { end end elseif ret_creds then - -- add credentials to a vault - self.retry_accounts[#self.retry_accounts + 1] = { - username = ret_creds.username, - password = ret_creds.password, - } + if not ret_creds.connect_phase then + -- add credentials to a vault + self.retry_accounts[#self.retry_accounts + 1] = { + username = ret_creds.username, + password = ret_creds.password, + } + end -- notify the main thread that there were an error on this coroutine thread_data.protocol_error = true diff --git a/nselib/data/publickeydb b/nselib/data/publickeydb new file mode 100644 index 000000000..fa81e9c48 --- /dev/null +++ b/nselib/data/publickeydb @@ -0,0 +1,3 @@ +AAAAB3NzaC1kc3MAAACBAISAE3CAX4hsxTw0dRc0gx8nQ41r3Vkj9OmG6LGeKWRmpy7C6vaExuupjxid76fd4aS56lCUEEoRlJ3zE93qoK9acI6EGqGQFLuDZ0fqMyRSX+ilf+1HDo/TRyuraggxp9Hj9LMpZVbpFATMm0+d9Xs7eLmaJjuMsowNlOf8NFdHAAAAFQCwdvqOAkR6QhuiAapQ/9iVuR0UAQAAAIBpLMo4dhSeWkChfv659WLPftxRrX/HR8YMD/jqa3R4PsVM2g6dQ1191nHugtdV7uaMeOqOJ/QRWeYM+UYwT0Zgx2LqvgVSjNDfdjk+ZRY8x3SmExFi62mKFoTGSOCXfcAfuanjaoF+sepnaiLUd+SoJShGYHoqR2QWiysTRqknlwAAAIBLEgYmr9XCSqjENFDVQPFELYKT7Zs9J87PjPS1AP0qF1OoRGZ5mefK6X/6VivPAUWmmmev/BuAs8M1HtfGeGGzMzDIiU/WZQ3bScLB1Ykrcjk7TOFD6xrnk/inYAp5l29hjidoAONcXoHmUAMYOKqn63Q2AsDpExVcmfj99/BlpQ==,root,Quantum DXi V1000 2.2.1 static root publickey accepted,source:http://www.exploit-db.com/exploits/32372/ +AAAAB3NzaC1kc3MAAACBAKwKBw7D4OA1H/uD4htdh04TBIHdbSjeXUSnWJsce8C0tvoB01Yarjv9TFj+tfeDYVWtUK1DA1JkyqSuoAtDANJzF4I6Isyd0KPrW3dHFTcg6Xlz8d3KEaHokY93NOmB/xWEkhme8b7Q0U2iZie2pgWbTLXV0FA+lhskTtPHW3+VAAAAFQDRyayUlVZKXEweF3bUe03zt9e8VQAAAIAEPK1k3Y6ErAbIl96dnUCnZjuWQ7xXy062pf63QuRWI6LYSscm3f1pEknWUNFr/erQ02pkfi2eP9uHl1TI1ql+UmJX3g3frfssLNZwWXAW0m8PbY3HZSs+f5hevM3ua32pnKDmbQ2WpvKNyycKHi81hSI14xMcdblJolhN5iY8/wAAAIAjEe5+0m/TlBtVkqQbUit+s/g+eB+PFQ+raaQdL1uztW3etntXAPH1MjxsAC/vthWYSTYXORkDFMhrO5ssE2rfg9io0NDyTIZt+VRQMGdi++dH8ptU+ldl2ZejLFdTJFwFgcfXz+iQ1mx6h9TPX1crE1KoMAVOj3yKVfKpLB1EkA==,root,Loadbalancer.org Enterprise VA 7.5.2 static root publickey accepted,source:http://www.exploit-db.com/exploits/32371/ +AAAAB3NzaC1yc2EAAAABIwAAAIEAvIhC5skTzxyHif/7iy3yhxuK6/OB13hjPqrskogkYFrcW8OK4VJT+5+Fx7wd4sQCnVn8rNqahw/x6sfcOMDI/Xvn4yKU4t8TnYf2MpUVr4ndz39L5Ds1n7Si1m2suUNxWbKv58I8+NMhlt2ITraSuTU0NGymWOc8+LNi+MHXdLk=,root,f5 BigIP static root publickey accepted,source:https://community.rapid7.com/community/metasploit/blog/2012/06/11/scanning-for-vulnerable-f5-bigips-with-metasploit diff --git a/nselib/libssh2-utility.lua b/nselib/libssh2-utility.lua new file mode 100644 index 000000000..7c2ba59b8 --- /dev/null +++ b/nselib/libssh2-utility.lua @@ -0,0 +1,177 @@ +--- +-- Utility functions for libssh2. +-- +-- Provides helper class for the libssh2 binding that abstracts away +-- details of running remote commands. +-- +-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html +-- @class module +-- @name libssh2-utility + +local stdnse = require "stdnse" +local table = require "table" + +local libssh2 = stdnse.silent_require "libssh2" + +SSHConnection = {} + +--- +-- Returns a new connection object. +-- +-- @return A connection object. +function SSHConnection:new () + local o = {} + setmetatable(o, self) + self.__index = self + return o +end + +--- +-- Sets up a connection with a server. +-- +-- @param host A host to connect to. +-- @param port A port to connect to. +-- @return true on success or nil on failure +function SSHConnection:connect (host, port) + self.session = libssh2.session_open(host, port.number) + if self.session then + return true + end +end + + +--- +-- Sets up a connection with a server. Call performed with pcall. +-- +-- @param host A host to connect to. +-- @param port A port to connect to. +-- @return true on success or error message on failure +-- @return error code if error was triggered +function SSHConnection:connect_pcall (host, port) + local status, err + status, self.session, err = pcall(libssh2.session_open, host, port.number) + return status, err +end + +--- +-- Runs a shell command on the remote host. +-- +-- @param cmd A command to run. +-- @return The command output. +function SSHConnection:run_remote (cmd) + if not (self.session and self.authenticated) then + return false + end + local channel = libssh2.open_channel(self.session) + libssh2.channel_exec(self.session, channel, cmd) + libssh2.channel_send_eof(self.session, channel) + local buff = {} + local data = "" + while not libssh2.channel_eof(channel) do + data = libssh2.channel_read(self.session, channel) + if data then + table.insert(buff, data) + end + end + return table.concat(buff) +end + +--- +-- Attempts to authenticate using provided credentials. +-- +-- @param username A username to authenticate as. +-- @param password A password to authenticate as. +-- @return true on success or false on failure. +function SSHConnection:password_auth (username, password) + if not self.session then + return false + end + if libssh2.userauth_password(self.session, username, password) then + self.authenticated = true + return true + else + return false + end +end + +--- +-- Attempts to authenticate using provided publickey. +-- +-- @param username A username to authenticate as. +-- @param privatekey_file A path to a privatekey. +-- @param passphrase A passphrase for the privatekey. +-- @return true on success or false on failure. +function SSHConnection:publickey_auth (username, privatekey_file, passphrase) + if not self.session then + return false + end + print(self.session) + print(username) + print(privatekey_file) + if libssh2.userauth_publickey(self.session, username, privatekey_file, passphrase) then + self.authenticated = true + return true + else + return false + end +end + +--- +-- Closes connection. +function SSHConnection:disconnect () + if self.session then + libssh2.session_close(self.session) + end +end + +--- +-- Sends ssh timeout +-- +-- @param ssh_timeout Time in miliseconds before considering the situation an error. +function SSHConnection:set_timeout (ssh_timeout) + if self.session then + libssh2.set_timeout(self.session, ssh_timeout) + end +end + +--- +-- Attempt to retrieve a list of supported authentication methods +-- +-- @param username A username to authenticate as. +-- @return A list with the authentication methods on success or false on failure. +function SSHConnection:list (username) + if not self.session then + return false + end + local status, methods = pcall(libssh2.userauth_list, self.session, username) + if status then + return methods + end + return false +end + +--- +-- Attempts to read public key file +-- +-- @param publickey An SSH public key file. +-- @return true on success or false on error. +-- @return publick key data on success or error code on error. +function SSHConnection:read_publickey (publickey) + local status, result = pcall(libssh2.read_publickey, publickey) + return status, result +end + +--- +-- Attempts authentication with publick key +-- +-- @param username A username to authenticate as. +-- @param key Base64 decrypted public key. +function SSHConnection:publickey_canauth (username, key) + if self.session then + libssh2.publickey_canauth(self.session, username, key) + end +end + +return _ENV + + diff --git a/nselib/libssh2.luadoc b/nselib/libssh2.luadoc new file mode 100644 index 000000000..dbbad360f --- /dev/null +++ b/nselib/libssh2.luadoc @@ -0,0 +1,120 @@ +--- +-- Provides a binding for the libssh2 library. +-- +-- SSH2 is a complex protocol and libssh2 simplifies many tasks involved in +-- interacting with ssh servers. This module provides bindings for some of the +-- most commonly used libssh2 functions. You may wish to use the functionality +-- in libssh2-utility instead, which wraps many of the functions here in an easier +-- to use class, SSHConnection. +-- +-- For perfomance reasons, the modules reuses the NSE's existing nsock socket +-- pool. +-- +-- @author Devin Bjelland +-- @author Sergey Khegay +-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html + +module "libssh2" + +--- Creates libssh2 session and performs handshake +-- @param host Host to connect to. +-- @param port Port to connect to. +-- @return session or nil on failure +function session_open(host, port) + +--- Returns SHA1 or MD5 hostkey hash of session +-- @param session Connected libssh2 session. +-- @param hashtype (optional) "sha1" or "md5" (sha1 is default) +-- @return hostkey hash of server +function hostkey_hash(session, hashtype) + +--- Sets timeout of libssh2 session +-- @param session Connected libssh2 session. +-- @param timeout Timeout for session in milliseconds. +function set_timeout(session, timeout) + +--- Returns list of authentication methods supported by the server +-- @param session Connected libssh2 session. +-- @return List of supported authentication methods/ +function userauth_list(session) + +--- Attempts to authenicate libssh2 session using provided credentials +-- @param username Username to authenicate as. +-- @param password Password to authenicate with. +-- @return true/false, depending on success +function userauth_password(session, username, password) + +--- Attempts to authenticate libssh2 session using provided publickey +-- @param session Connected libssh2 session +-- @param username Username to authenicate as +-- @param privatekeyfile File containing privatekey +-- @param passphrase Passphrase for privatekey +-- @param publickeyfile File containing publickey. Not necessary if libssh2 is +-- compiled against OpenSSL +-- @return true/false, depending on success +function userauth_publickey(session, username, privatekeyfile, passphrase publickeyfile) + +--- Read publickey from id_*.pub type key file +-- @param publickeyfile File containing publickey +-- @return string containing raw key data +function read_publickey(publickeyfile) + +--- Checks to see if ssh server accepts public key for authentication as given user. +-- This doesn't require the private key as it doesn't finish authenticating. +-- @param session Connected libssh2 session +-- @param username Username to authenicate as +-- @param publickeydata String containing raw publickey blob +-- @return true/false, depending on whether user can authenticate with given key +function publickey_canauth(session, username, publickeydata) + +--- Opens channel on authenticated ssh2 session and sets it to pseudo +-- terminal mode. +-- @param session Authenticated libssh2 session +-- @return libssh2 channel +function open_channel(session) + +--- Reads data from stdin on libssh2 channel. +-- @param session Authenticated libssh2 session +-- @param channel Open libssh2 channel +-- @return string containing data read from channel +function channel_read(session, channel) + +--- Reads data from stderr on libssh2 channel. +-- @param session Authenticated libssh2 session +-- @param channel Open libssh2 channel +-- @return string containing data read from channel +function channel_read_stderr(session, channel) + +--- Writes data to libssh2 channel. Not garenteed to write entire buffer. +-- @param session Authenticated libssh2 session +-- @param channel Open libssh2 channel +-- @param buffer String containing data to be written +-- @return Number of bytes written to channel +function channel_write(session, channel, buffer) + +--- Executes command on libssh2 channel and returns output +-- @param session Authenticated libssh2 session +-- @param channel Open libssh2 channel +-- @param cmd String containing command to execute +-- @return String containing output from command +function channel_exec(session, channel, cmd) + +--- Sends EOF on libssh2 channel. Note that the server may continue to send data +-- until it sends its own EOF (which can be checked with channel_eof() +-- @param session Authenticated libssh2 session +-- @param channel Open libssh2 channel +function channel_send_eof(session, channel) + +--- Checks if server has sent EOF on libssh2 channel +-- @param channel Open libssh2 channel +-- @return true/false depending on whether server has send EOF +function channel_eof(channel) + +--- Gracefully closes open libssh2 channel +-- @param session Authenticated libssh2 session +-- @param channel Open libssh2 channel +function channel_close(session, channel) + +--- Gracefully closes connected libssh2 session +-- @param session Connected libssh2 session +function session_close(session) diff --git a/scripts/ssh-auth-methods.nse b/scripts/ssh-auth-methods.nse new file mode 100644 index 000000000..9113a8025 --- /dev/null +++ b/scripts/ssh-auth-methods.nse @@ -0,0 +1,38 @@ +local shortport = require "shortport" +local stdnse = require "stdnse" +local libssh2_util = require "libssh2-utility" + +description = [[ +Returns authenication methods a ssh server supports. +]] + +--- +-- @usage +-- nmap -p 22 --script ssh-auth-methods --script-args="ssh.user=" +-- +-- @output +-- 22/tcp open ssh syn-ack +-- | ssh-auth-methods: +-- | Supported authentication methods: +-- | publickey +-- |_ password + +author = "Devin Bjelland" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" + +local username = stdnse.get_script_args "ssh.user" or stdnse.generate_random_string(5) +portrule = shortport.port_or_service(22, 'ssh') + +function action (host, port) + local result = stdnse.output_table() + local helper = libssh2_util.SSHConnection:new() + if not helper:connect(host, port) then + return "Failed to connect to ssh server" + end + + local authmethods = helper:list(username) + + result["Supported authentication methods"] = authmethods + + return result +end diff --git a/scripts/ssh-brute.nse b/scripts/ssh-brute.nse new file mode 100644 index 000000000..249cdd208 --- /dev/null +++ b/scripts/ssh-brute.nse @@ -0,0 +1,114 @@ +local shortport = require "shortport" +local stdnse = require "stdnse" +local brute = require "brute" +local creds = require "creds" + +local libssh2_util = require "libssh2-utility" + +description = [[ +Performs brute-force password guessing against ssh servers. +]] + +--- +-- @usage +-- nmap -p 22 --script ssh-brute --script-args userdb=users.lst,passdb=pass.lst \ +-- --script-args ssh-brute.timeout=4s +-- +-- @output +-- 22/ssh open ssh +-- | ssh-brute: +-- | Accounts +-- | username:password +-- | Statistics +-- |_ Performed 32 guesses in 25 seconds. +-- +-- @args ssh-brute.timeout Connection timeout (default: "5s") + +author = "Devin Bjelland" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = { + 'brute', + 'intrusive', +} + +portrule = shortport.port_or_service(22, 'ssh') + +local arg_timeout = stdnse.get_script_args(SCRIPT_NAME .. ".timeout") or "5s" + +Driver = { + new = function (self, host, port, options) + stdnse.debug(2, "creating brute driver") + local o = { + helper = libssh2_util.SSHConnection:new(), + } + setmetatable(o, self) + self.__index = self + o.host = host + o.port = port + o.options = options + return o + end, + + connect = function (self) + local status, err = self.helper:connect_pcall(self.host, self.port) + if not status then + stdnse.debug(2, "libssh2 error: %s", self.helper.session) + local err = brute.Error:new(self.helper.session) + err:setReduce(true) + return false, err + elseif not self.helper.session then + stdnse.debug(2, "failure to connect: %s", err) + local err = brute.Error:new(err) + err:setAbort(true) + return false, err + else + self.helper:set_timeout(self.options.ssh_timeout) + return true + end + end, + + login = function (self, username, password) + stdnse.verbose(1, "Trying username/password pair: %s:%s", username, password) + local status, resp = self.helper:password_auth(username, password) + if status then + return true, creds.Account:new(username, password, creds.State.VALID) + end + return false, brute.Error:new "Incorrect password" + end, + + disconnect = function (self) + return self.helper:disconnect() + end, +} + +local function password_auth_allowed (host, port) + local helper = libssh2_util.SSHConnection:new() + if not helper:connect(host, port) then + return "Failed to connect to ssh server" + end + local methods = helper:list "root" + if methods then + for _, value in pairs(methods) do + if value == "password" then + return true + end + end + end + return false +end + +function action (host, port) + local timems = stdnse.parse_timespec(arg_timeout) --todo: use this! + local ssh_timeout = 1000 * timems + if password_auth_allowed(host, port) then + local options = { + ssh_timeout = ssh_timeout, + } + local engine = brute.Engine:new(Driver, host, port, options) + engine.options.script_name = SCRIPT_NAME + local _, result = engine:start() + return result + else + return "Password authenication not allowed" + end +end diff --git a/scripts/ssh-publickey-acceptance.nse b/scripts/ssh-publickey-acceptance.nse new file mode 100644 index 000000000..75271597a --- /dev/null +++ b/scripts/ssh-publickey-acceptance.nse @@ -0,0 +1,113 @@ +local shortport = require "shortport" +local stdnse = require "stdnse" +local base64 = require "base64" +local string = require "string" +local table = require "table" +local io = require "io" + +local libssh2_util = require "libssh2-utility" + +description = [[ +This script takes a table of paths to private keys, passphrases, and usernames and checks each pair to +see if the target ssh server accepts them for publickey authentication. If no keys are given or the known-bad option is given, the script will check if a list of known static public keys are accepted for authentication. +]] + +--- +-- @usage +-- nmap -p 22 --script ssh-publickey-acceptance --script-args "ssh.usernames={'root', 'user'}, ssh.privatekeys={'./id_rsa1', './id_rsa2'}" +-- +-- @usage +-- nmap -p 22 --script ssh-publickey-acceptance --script-args 'ssh.usernames={"root", "user"}, publickeys={"./id_rsa1.pub", "./id_rsa2.pub"}' +-- +-- @output +-- 22/tcp open ssh syn-ack +-- | ssh-publickey-acceptance: +-- | Accepted Public Keys: +-- |_ Key ./id_rsa1 accepted for user root +-- +-- @args ssh.privatekeys Table containing filenames of privatekeys to test +-- @args ssh.publickeys Table containing filenames of publickkeys to test +-- @args ssh.usernames Table containing usernames to check +-- @args knownbad If specified, check if keys from publickeydb are accepted +-- @args publickeydb Specifies alternative publickeydb + +author = "Devin Bjelland" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" + +local privatekeys = stdnse.get_script_args "ssh.privatekeys" +local usernames = stdnse.get_script_args "ssh.usernames" +local knownbad = stdnse.get_script_args "known-bad" +local publickeys = stdnse.get_script_args "ssh.publickeys" +local publickeydb = stdnse.get_script_args "publickeydb" or "nselib/data/publickeydb" +portrule = shortport.port_or_service(22, 'ssh') + +function action (host, port) + local result = stdnse.output_table() + local r = {} + local helper = libssh2_util.SSHConnection:new() + helper:connect(host, port) + if publickeys and usernames then + for j = 1, #usernames do + for i = 1, #publickeys do + stdnse.debug("Checking key: " .. publickeys[i] .. " for user " .. usernames[j]) + local status, result = helper:read_publickey(publickeys[i]) + if not status then + stdnse.verbose("Error reading key: " .. result) + elseif helper:publickey_canauth(usernames[j], result) then + table.insert(r, "Key " .. publickeys[i] .. " accepted for user " .. usernames[j]) + stdnse.verbose("Found accepted key: " .. publickeys[i] .. " for user " .. usernames[j]) + helper:disconnect() + helper:connect(host, port) + end + end + end + end + + if knownbad or not (privatekeys and publickeys) then + for line in io.lines(publickeydb) do + local sections = {} + for section in string.gmatch(line, '([^,]+)') do + table.insert(sections, section) + end + local key = sections[1] + local user = sections[2] + local msg = sections[3] + stdnse.debug("Checking key: " .. key .. " for user " .. user) + key = base64.dec(key) + if helper:publickey_canauth(user, key) then + table.insert(r, msg) + stdnse.verbose("Found accepted key: " .. msg) + helper:disconnect() + helper:connect(host, port) + end + end + end + + if privatekeys and usernames then + for j = 1, #usernames do + for i = 1, #privatekeys do + stdnse.debug("Checking key: " .. privatekeys[i] .. " for user " .. usernames[j]) + if not helper:publickey_auth(usernames[j], privatekeys[i], "") then + helper:disconnect() + stdnse.verbose "Failed to authenticate" + helper:connect(host, port) + else + table.insert(r, "Key " .. privatekeys[i] .. " accepted for user " .. usernames[j]) + stdnse.verbose("Found accepted key: " .. privatekeys[i] .. " for user " .. usernames[j]) + + helper:disconnect() + helper:connect(host, port) + end + + end + end + end + + if #r > 0 then + result["Accepted Public Keys"] = r + else + result["Accepted Public Keys"] = "No public keys accepted" + end + + return result +end diff --git a/scripts/ssh-run.nse b/scripts/ssh-run.nse new file mode 100644 index 000000000..dd423bcc7 --- /dev/null +++ b/scripts/ssh-run.nse @@ -0,0 +1,83 @@ +local stdnse = require "stdnse" +local shortport = require "shortport" +local table = require "table" +local libssh2_util = require "libssh2-utility" + +description = [[ +Runs remote command on ssh server and returns command output. +]] + +--- +-- @usage nmap -p 22 -v -d --script=ssh-run --datadir=./ \ +-- --script-args="ssh-run.cmd=ls -l /, ssh-run.username=myusername, ssh-run.password=mypassword" +-- +-- @output +-- 22/tcp open ssh syn-ack 0 +-- | run-remote: +-- | output: +-- | total 124 +-- | drwxr-xr-x 2 root root 4096 Jun 23 09:34 bin +-- | drwxr-xr-x 3 root root 4096 Jun 19 12:42 boot +-- | drwxr-xr-x 2 root root 4096 Feb 6 2013 cdrom +-- | drwxr-xr-x 16 root root 4340 Jul 17 13:37 dev +-- | drwxr-xr-x 162 root root 12288 Jul 20 12:10 etc +-- | drwxr-xr-x 15 root root 4096 Jun 23 15:20 home +-- | ... +-- |_drwxr-xr-x 14 root root 4096 Jun 6 14:58 var +-- +-- @args ssh-run.username Username to authenticate as +-- @args ssh-run.password Password to use if using password authentication +-- @args ssh-run.privatekey Privatekeyfile to use if using publickey authentication +-- @args ssh-run.passphrase Passphrase for privatekey if using publickey authentication +-- @args ssh-run.cmd Command to run on remote server + + +author = "Devin Bjelland" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" + +categories = { + 'intrusive', +} + +portrule = shortport.port_or_service(22, 'ssh') + +local username = stdnse.get_script_args 'ssh-run.username' +local cmd = stdnse.get_script_args 'ssh-run.cmd' +local password = stdnse.get_script_args 'ssh-run.password' +local privatekey = stdnse.get_script_args 'ssh-run.privatekey' +local passphrase = stdnse.get_script_args 'ssh-run.passphrase' + +function action (host, port) + local conn = libssh2_util.SSHConnection:new() + if not conn:connect(host, port) then + return "Failed to connect to ssh server" + end + if username and password and cmd then + if not conn:password_auth(username, password) then + conn:disconnect() + stdnse.verbose "Failed to authenticate" + return "Authentication Failed" + else + stdnse.verbose "Authenticated" + end + elseif username and privatekey and cmd then + if not conn:publickey_auth(username, privatekey, passphrase) then + conn:disconnect() + stdnse.verbose "Failed to authenticate" + return "Authentication Failed" + else + stdnse.verbose "Authenticated" + end + + else + stdnse.verbose "Failed to specify credentials and command to run." + return "Failed to specify credentials and command to run." + end + stdnse.verbose("Running command: " .. cmd) + local output, err_output = conn:run_remote(cmd) + stdnse.verbose("Output of command: " .. output) + local result = stdnse.output_table() + result.output = {} + table.insert(result.output, output) + return result +end