]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Rewrite the hash function detection. Build an actual test program using
authorJoerg Sonnenberger <joerg.sonnenberger@gmail.com>
Sun, 9 May 2010 23:48:04 +0000 (19:48 -0400)
committerJoerg Sonnenberger <joerg.sonnenberger@gmail.com>
Sun, 9 May 2010 23:48:04 +0000 (19:48 -0400)
archive_hash.h and link against libcrypto if needed.

Fixes issue #73 and #86.

SVN-Revision: 2375

CMakeLists.txt
build/cmake/config.h.in
configure.ac
libarchive/archive_hash.h

index d9b6ac7c0ed0757d1809769a9966f584fb57b726..ec82efb85dc9ee70fd1e5e1b60041f4b0cb51588 100644 (file)
@@ -268,72 +268,70 @@ LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H)
 #
 IF(ENABLE_OPENSSL)
   FIND_PACKAGE(OpenSSL)
-ELSE()
-  SET(OPENSSL_FOUND 0)
 ENDIF()
-IF(OPENSSL_FOUND)
-  INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
-  LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_LIBRARIES})
-ELSE()
-  # Block OpenSSL checks and override cached results.
-  SET(HAVE_OPENSSL_MD5_H 0)
-  SET(HAVE_OPENSSL_RIPEMD_H 0)
-  SET(HAVE_OPENSSL_SHA_H 0)
-  SET(HAVE_OPENSSL_SHA256_INIT 0)
-  SET(HAVE_OPENSSL_SHA384_INIT 0)
-  SET(HAVE_OPENSSL_SHA512_INIT 0)
-ENDIF()
-#
-# Check MD5/RMD160/SHA headers
-#
-LA_CHECK_INCLUDE_FILE("md5.h" HAVE_MD5_H)
-LA_CHECK_INCLUDE_FILE("openssl/md5.h" HAVE_OPENSSL_MD5_H)
-LA_CHECK_INCLUDE_FILE("openssl/ripemd.h" HAVE_OPENSSL_RIPEMD_H)
-LA_CHECK_INCLUDE_FILE("openssl/sha.h" HAVE_OPENSSL_SHA_H)
-LA_CHECK_INCLUDE_FILE("ripemd.h" HAVE_RIPEMD_H)
-LA_CHECK_INCLUDE_FILE("rmd160.h" HAVE_RMD160_H)
-LA_CHECK_INCLUDE_FILE("sha.h" HAVE_SHA_H)
-LA_CHECK_INCLUDE_FILE("sha1.h" HAVE_SHA1_H)
-LA_CHECK_INCLUDE_FILE("sha2.h" HAVE_SHA2_H)
-LA_CHECK_INCLUDE_FILE("sha256.h" HAVE_SHA256_H)
-
-#
-# Find MD5/RMD160/SHA library
-#
-FIND_LIBRARY(CRYPTO_LIBRARY NAMES crypto)
-IF(CRYPTO_LIBRARY)
-  LIST(APPEND ADDITIONAL_LIBS ${CRYPTO_LIBRARY})
-ELSE(CRYPTO_LIBRARY)
-  IF(NOT OPENSSL_FOUND)
-    FIND_LIBRARY(MD_LIBRARY NAMES md)
-    IF(MD_LIBRARY)
-      LIST(APPEND ADDITIONAL_LIBS ${MD_LIBRARY})
-    ENDIF(MD_LIBRARY)
-  ENDIF(NOT OPENSSL_FOUND)
-ENDIF(CRYPTO_LIBRARY)
-#
-# Check MD5/RMD160/SHA functions
-#
-SET(CMAKE_REQUIRED_LIBRARIES ${ADDITIONAL_LIBS})
-IF(HAVE_MD5_H)
-  CHECK_SYMBOL_EXISTS(MD5Init                  "md5.h"         HAVE_MD5INIT)
-ENDIF(HAVE_MD5_H)
-IF(HAVE_RMD160_H)
-  CHECK_SYMBOL_EXISTS(RMD160Init               "rmd160.h"      HAVE_RMD160INIT)
-ENDIF(HAVE_RMD160_H)
-IF(HAVE_SHA2_H)
-  CHECK_SYMBOL_EXISTS(SHA256Init               "sha2.h"        HAVE_SHA256INIT)
-  CHECK_SYMBOL_EXISTS(SHA384Init               "sha2.h"        HAVE_SHA384INIT)
-  CHECK_SYMBOL_EXISTS(SHA512Init               "sha2.h"        HAVE_SHA512INIT)
-  CHECK_SYMBOL_EXISTS(SHA256_Init              "sha2.h"        HAVE_SHA256_INIT)
-  CHECK_SYMBOL_EXISTS(SHA384_Init              "sha2.h"        HAVE_SHA384_INIT)
-  CHECK_SYMBOL_EXISTS(SHA512_Init              "sha2.h"        HAVE_SHA512_INIT)
-ELSEIF(HAVE_OPENSSL_SHA_H)
-  CHECK_SYMBOL_EXISTS(SHA256_Init              "openssl/sha.h" HAVE_OPENSSL_SHA256_INIT)
-  CHECK_SYMBOL_EXISTS(SHA384_Init              "openssl/sha.h" HAVE_OPENSSL_SHA384_INIT)
-  CHECK_SYMBOL_EXISTS(SHA512_Init              "openssl/sha.h" HAVE_OPENSSL_SHA512_INIT)
-ENDIF()
-SET(CMAKE_REQUIRED_LIBRARIES "")
+
+MACRO(CHECK_MD HASH IMPLEMENTATIONS)
+    FOREACH(IMPLEMENTATION ${IMPLEMENTATIONS})
+       IF (CHECK_MD_${HASH})
+           BREAK()
+       ENDIF (CHECK_MD_${HASH})
+       STRING(TOLOWER "${HASH}" lower_hash)
+       STRING(TOUPPER "${HASH}" hash)
+
+       IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+           INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
+           LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_LIBRARIES})
+       ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND)
+
+       SET(SOURCE "#define ${hash}_COMPILE_TEST
+#define ARCHIVE_HASH_${hash}_${IMPLEMENTATION}
+#define __LIBARCHIVE_BUILD
+#include \"archive_hash.h\"
+
+int
+main(int argc, char **argv)
+{
+       archive_${lower_hash}_ctx ctx;
+
+       archive_${lower_hash}_init(&ctx);
+       archive_${lower_hash}_update(&ctx, *argv, argc);
+       archive_${lower_hash}_final(&ctx, *argv);
+       return 0;
+}
+")
+
+       FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c" "${SOURCE}")
+       MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION}")
+
+       TRY_COMPILE(CHECK_MD_${HASH}
+         ${CMAKE_BINARY_DIR}
+         ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
+         CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=/home/joerg/wd/libarchive-full/trunk/libarchive"
+         OUTPUT_VARIABLE OUTPUT)
+
+       IF (CHECK_MD_${HASH})
+           MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} -- found")
+           SET(ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} 1)
+           BREAK()
+       ENDIF(CHECK_MD_${HASH})
+
+       MESSAGE(STATUS "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} -- not found")
+       FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+           "Checking support for ARCHIVE_HASH_${HASH}_${IMPLEMENTATION} failed with the following output:\n"
+           "${OUTPUT}\n"
+           "Source file was:\n${SOURCE}\n")
+    ENDFOREACH(IMPLEMENTATION)
+ENDMACRO(CHECK_MD HASH IMPLEMENTATIONS)
+
+#
+# Check MD5/RMD160/SHA support
+#
+CHECK_MD(MD5 "LIBC;WIN;OPENSSL")
+CHECK_MD(RMD160 "LIBC;WIN;OPENSSL")
+CHECK_MD(SHA1 "LIBC;WIN;OPENSSL")
+CHECK_MD(SHA256 "LIBC;LIBC2;LIBC3;WIN;OPENSSL")
+CHECK_MD(SHA384 "LIBC;LIBC2;LIBC3;WIN;OPENSSL")
+CHECK_MD(SHA512 "LIBC;LIBC2;LIBC3;WIN;OPENSSL")
 
 #
 # Find Libxml2
index e5c8cc30ca3eae8aac6f9c1cd47ef66fdf03e14f..6aef667133d2668a18f605e087c6ea2c2b07ceb5 100644 (file)
@@ -1,5 +1,59 @@
 /* config.h.  Generated from config.h.cmake by cmake configure */
 
+/* MD5 via ARCHIVE_HASH_MD5_LIBC supported. */
+#cmakedefine ARCHIVE_HASH_MD5_LIBC
+
+/* MD5 via ARCHIVE_HASH_MD5_OPENSSL supported. */
+#cmakedefine ARCHIVE_HASH_MD5_OPENSSL
+
+/* RMD160 via ARCHIVE_HASH_RMD160_LIBC supported. */
+#cmakedefine ARCHIVE_HASH_RMD160_LIBC
+
+/* RMD160 via ARCHIVE_HASH_RMD160_OPENSSL supported. */
+#cmakedefine ARCHIVE_HASH_RMD160_OPENSSL
+
+/* SHA1 via ARCHIVE_HASH_SHA1_LIBC supported. */
+#cmakedefine ARCHIVE_HASH_SHA1_LIBC
+
+/* SHA1 via ARCHIVE_HASH_SHA1_OPENSSL supported. */
+#cmakedefine ARCHIVE_HASH_SHA1_OPENSSL
+
+/* SHA256 via ARCHIVE_HASH_SHA256_LIBC supported. */
+#cmakedefine ARCHIVE_HASH_SHA256_LIBC
+
+/* SHA256 via ARCHIVE_HASH_SHA256_LIBC2 supported. */
+#cmakedefine ARCHIVE_HASH_SHA256_LIBC2
+
+/* SHA256 via ARCHIVE_HASH_SHA256_LIBC3 supported. */
+#cmakedefine ARCHIVE_HASH_SHA256_LIBC3
+
+/* SHA256 via ARCHIVE_HASH_SHA256_OPENSSL supported. */
+#cmakedefine ARCHIVE_HASH_SHA256_OPENSSL
+
+/* SHA384 via ARCHIVE_HASH_SHA384_LIBC supported. */
+#cmakedefine ARCHIVE_HASH_SHA384_LIBC
+
+/* SHA384 via ARCHIVE_HASH_SHA384_LIBC2 supported. */
+#cmakedefine ARCHIVE_HASH_SHA384_LIBC2
+
+/* SHA384 via ARCHIVE_HASH_SHA384_LIBC3 supported. */
+#cmakedefine ARCHIVE_HASH_SHA384_LIBC3
+
+/* SHA384 via ARCHIVE_HASH_SHA384_OPENSSL supported. */
+#cmakedefine ARCHIVE_HASH_SHA384_OPENSSL
+
+/* SHA512 via ARCHIVE_HASH_SHA512_LIBC supported. */
+#cmakedefine ARCHIVE_HASH_SHA512_LIBC
+
+/* SHA512 via ARCHIVE_HASH_SHA512_LIBC2 supported. */
+#cmakedefine ARCHIVE_HASH_SHA512_LIBC2
+
+/* SHA512 via ARCHIVE_HASH_SHA512_LIBC3 supported. */
+#cmakedefine ARCHIVE_HASH_SHA512_LIBC3
+
+/* SHA512 via ARCHIVE_HASH_SHA512_OPENSSL supported. */
+#cmakedefine ARCHIVE_HASH_SHA512_OPENSSL
+
 /* Version number of bsdcpio */
 #cmakedefine BSDCPIO_VERSION_STRING "${BSDCPIO_VERSION_STRING}"
 
 /* Define to 1 if you have the `mbrtowc' function. */
 #cmakedefine HAVE_MBRTOWC 1
 
-/* Define to 1 if you have the `MD5Init' function. */
-#cmakedefine HAVE_MD5INIT 1
-
-/* Define to 1 if you have the <md5.h> header file. */
-#cmakedefine HAVE_MD5_H 1
-
 /* Define to 1 if you have the `memmove' function. */
 #cmakedefine HAVE_MEMMOVE 1
 
 /* Define to 1 if you have the `nl_langinfo' function. */
 #cmakedefine HAVE_NL_LANGINFO 1
 
-/* Define to 1 if you have the <openssl/md5.h> header file. */
-#cmakedefine HAVE_OPENSSL_MD5_H 1
-
-/* Define to 1 if you have the <openssl/ripemd.h> header file. */
-#cmakedefine HAVE_OPENSSL_RIPEMD_H 1
-
-/* Define to 1 if you have the <openssl/sha.h> header file. */
-#cmakedefine HAVE_OPENSSL_SHA_H 1
-
-/* Define to 1 if your openssl has the `SHA256_Init' function. */
-#cmakedefine HAVE_OPENSSL_SHA256_INIT 1
-
-/* Define to 1 if your openssl has the `SHA384_Init' function. */
-#cmakedefine HAVE_OPENSSL_SHA384_INIT 1
-
-/* Define to 1 if your openssl has the `SHA512_Init' function. */
-#cmakedefine HAVE_OPENSSL_SHA512_INIT 1
-
 /* Define to 1 if you have the <paths.h> header file. */
 #cmakedefine HAVE_PATHS_H 1
 
 /* Define to 1 if you have the <regex.h> header file. */
 #cmakedefine HAVE_REGEX_H 1
 
-/* Define to 1 if you have the <ripemd.h> header file. */
-#cmakedefine HAVE_RIPEMD_H 1
-
-/* Define to 1 if you have the `RIPEMD160Init' function. */
-#cmakedefine HAVE_RMD160INIT 1
-
-/* Define to 1 if you have the <rmd160.h> header file. */
-#cmakedefine HAVE_RMD160_H 1
-
 /* Define to 1 if you have the `select' function. */
 #cmakedefine HAVE_SELECT 1
 
 /* Define to 1 if you have the `setlocale' function. */
 #cmakedefine HAVE_SETLOCALE 1
 
-/* Define to 1 if you have the `SHA1Init' function. */
-#cmakedefine HAVE_SHA1INIT 1
-
-/* Define to 1 if you have the `SHA1_Init' function. */
-#cmakedefine HAVE_SHA1_INIT 1
-
-/* Define to 1 if you have the <sha1.h> header file. */
-#cmakedefine HAVE_SHA1_H 1
-
-/* Define to 1 if you have the `SHA256Init' function. */
-#cmakedefine HAVE_SHA256INIT 1
-
-/* Define to 1 if you have the `SHA256_Init' function. */
-#cmakedefine HAVE_SHA256_INIT 1
-
-/* Define to 1 if you have the <sha256.h> header file. */
-#cmakedefine HAVE_SHA256_H 1
-
-/* Define to 1 if you have the <sha2.h> header file. */
-#cmakedefine HAVE_SHA2_H 1
-
-/* Define to 1 if you have the `SHA384Init' function. */
-#cmakedefine HAVE_SHA384INIT 1
-
-/* Define to 1 if you have the `SHA384_Init' function. */
-#cmakedefine HAVE_SHA384_INIT 1
-
-/* Define to 1 if you have the `SHA512Init' function. */
-#cmakedefine HAVE_SHA512INIT 1
-
-/* Define to 1 if you have the `SHA512_Init' function. */
-#cmakedefine HAVE_SHA512_INIT 1
-
-/* Define to 1 if you have the <sha.h> header file. */
-#cmakedefine HAVE_SHA_H 1
-
 /* Define to 1 if you have the <signal.h> header file. */
 #cmakedefine HAVE_SIGNAL_H 1
 
index ba05c1a9f92e68f542a1bc9c5000d1f084cbcc88..53d211a6bb31409b876a01f796dd76870dc6756e 100644 (file)
@@ -260,57 +260,63 @@ if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then
   fi
 fi
 
-AC_CHECK_HEADERS([md5.h ripemd.h rmd160.h sha.h sha1.h sha2.h sha256.h])
-# Common names for libc implementation on NetBSD and OpenBSD
-AC_CHECK_FUNCS(MD5Init RMD160Init SHA1Init)
-# SHA2 on NetBSD and older OpenBSD
-AC_CHECK_FUNCS(SHA256_Init SHA384_Init SHA512_Init)
-# SHA2 on newer OpenBSD
-AC_CHECK_FUNCS(SHA256Init SHA384Init SHA512Init)
-
-if test "x$with_openssl" != "xno"; then
-  if test "$ac_cv_func_MD5Init" != "yes"; then
-    AC_CHECK_HEADERS([openssl/md5.h])
-    AC_SEARCH_LIBS([MD5_Init], [crypto])
-  fi
-  if test "$ac_cv_func_RMD160Init" != "yes"; then
-    AC_CHECK_HEADERS([openssl/ripemd.h])
-    AC_SEARCH_LIBS([RIPEMD160_Init], [crypto])
-  fi
-  if test "$ac_cv_func_SHA1Init" != "yes"; then
-    AC_CHECK_HEADERS([openssl/sha.h])
-    AC_SEARCH_LIBS([SHA1_Init], [crypto])
+AC_DEFUN([MD_CHECK], [
+  if test "$found_$1" != yes; then
+    saved_LIBS="$LIBS"
+    saved_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$CPPFLAGS -I$srcdir/libarchive"
+    LIBS="$LIBS $4"
+    AC_MSG_CHECKING([support for ARCHIVE_HASH_$1_$2])
+    AC_LINK_IFELSE([
+#define $1_COMPILE_TEST
+#define ARCHIVE_HASH_$1_$2
+#define __LIBARCHIVE_BUILD
+#include "archive_hash.h"
+
+int
+main(int argc, char **argv)
+{
+       archive_$3_ctx ctx;
+
+       archive_$3_init(&ctx);
+       archive_$3_update(&ctx, *argv, argc);
+       archive_$3_final(&ctx, *argv);
+       return 0;
+}
+],
+    [ AC_MSG_RESULT([yes])
+      found_$1=yes
+      mdLIBS="$mdLIBS $4"
+      AC_DEFINE(ARCHIVE_HASH_$1_$2, 1, [ $1 via ARCHIVE_HASH_$1_$2 supported.])
+    ],
+    [ AC_MSG_RESULT([no])])
+    LIBS="$saved_LIBS"
+    CPPFLAGS="$saved_CPPFLAGS"
   fi
+])
 
-  AC_CHECK_HEADERS([openssl/sha.h])
-  if test "$ac_cv_func_SHA256Init" != "yes" &&
-    test "$ac_cv_func_SHA256_Init" != "yes"; then
-      AC_SEARCH_LIBS([SHA256_Init], [crypto])
-      if test "$ac_cv_func_SHA256_Init" = "yes" &&
-        test "$ac_cv_header_openssl_sha_h" = "yes"; then
-        AC_DEFINE(HAVE_OPENSSL_SHA256_INIT, 1,
-         [Define to 1 if your openssl has the `SHA256_Init' function.])
-      fi
-  fi
-  if test "$ac_cv_func_SHA384Init" != "yes" &&
-    test "$ac_cv_func_SHA384_Init" != "yes"; then
-      AC_SEARCH_LIBS([SHA384_Init], [crypto])
-      if test "$ac_cv_func_SHA384_Init" = "yes" &&
-        test "$ac_cv_header_openssl_sha_h" = "yes"; then
-        AC_DEFINE(HAVE_OPENSSL_SHA384_INIT, 1,
-         [Define to 1 if your openssl has the `SHA384_Init' function.])
-      fi
-  fi
-  if test "$ac_cv_func_SHA512Init" != "yes" &&
-    test "$ac_cv_func_SHA512_Init" != "yes"; then
-      AC_SEARCH_LIBS([SHA512_Init], [crypto])
-      if test "$ac_cv_func_SHA512_Init" = "yes" &&
-        test "$ac_cv_header_openssl_sha_h" = "yes"; then
-        AC_DEFINE(HAVE_OPENSSL_SHA512_INIT, 1,
-         [Define to 1 if your openssl has the `SHA512_Init' function.])
-      fi
-  fi
+MD_CHECK(MD5, LIBC, md5)
+MD_CHECK(RMD160, LIBC, rmd160)
+MD_CHECK(SHA1, LIBC, sha1)
+MD_CHECK(SHA256, LIBC, sha256)
+MD_CHECK(SHA256, LIBC2, sha256)
+MD_CHECK(SHA256, LIBC3, sha256)
+MD_CHECK(SHA384, LIBC, sha384)
+MD_CHECK(SHA384, LIBC2, sha384)
+MD_CHECK(SHA384, LIBC3, sha384)
+MD_CHECK(SHA512, LIBC, sha512)
+MD_CHECK(SHA512, LIBC2, sha512)
+MD_CHECK(SHA512, LIBC3, sha512)
+
+if test "x$with_openssl" != "xno"; then
+    MD_CHECK(MD5, OPENSSL, md5, -lcrypto)
+    MD_CHECK(RMD160, OPENSSL, rmd160, -lcrypto)
+    MD_CHECK(SHA1, OPENSSL, sha1, -lcrypto)
+    MD_CHECK(SHA256, OPENSSL, sha256, -lcrypto)
+    MD_CHECK(SHA384, OPENSSL, sha384, -lcrypto)
+    MD_CHECK(SHA512, OPENSSL, sha512, -lcrypto)
 fi
+LIBS="$LIBS $mdLIBS"
 
 # TODO: Give the user the option of using a pre-existing system
 # libarchive.  This will define HAVE_LIBARCHIVE which will cause
index 1a3b3344dc811039689eaed9824aff7bc3dbe718..ad4a667c95c2701432997521a6f52900a02d79a4 100644 (file)
 #error This header is only to be used internally to libarchive.
 #endif
 
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
 /*
  * Hash function support in various Operating Systems:
  *
  * - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name
  */
 
-#if defined(HAVE_MD5_H) && defined(HAVE_MD5INIT)
+#if defined(ARCHIVE_HASH_MD5_LIBC)
 #  include <md5.h>
 #  define ARCHIVE_HAS_MD5
 typedef MD5_CTX archive_md5_ctx;
 #  define archive_md5_init(ctx)                        MD5Init(ctx)
 #  define archive_md5_final(ctx, buf)          MD5Final(buf, ctx)
 #  define archive_md5_update(ctx, buf, n)      MD5Update(ctx, buf, n)
-#elif defined(HAVE_OPENSSL_MD5_H)
+#elif defined(ARCHIVE_HASH_MD5_OPENSSL)
 #  include <openssl/md5.h>
 #  define ARCHIVE_HAS_MD5
 typedef MD5_CTX archive_md5_ctx;
 #  define archive_md5_init(ctx)                        MD5_Init(ctx)
 #  define archive_md5_final(ctx, buf)          MD5_Final(buf, ctx)
 #  define archive_md5_update(ctx, buf, n)      MD5_Update(ctx, buf, n)
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(CALG_MD5)
+#elif defined(ARCHIVE_HASH_MD5_WIN)
 #  define ARCHIVE_HAS_MD5
 typedef MD5_CTX archive_md5_ctx;
 #  define archive_md5_init(ctx)                        MD5_Init(ctx)
@@ -70,14 +74,14 @@ typedef MD5_CTX archive_md5_ctx;
 #  define archive_md5_update(ctx, buf, n)      MD5_Update(ctx, buf, n)
 #endif
 
-#if defined(HAVE_RMD160_H) && defined(HAVE_RMD160INIT)
+#if defined(ARCHIVE_HASH_RMD160_LIBC)
 #  include <rmd160.h>
 #  define ARCHIVE_HAS_RMD160
 typedef RMD160_CTX archive_rmd160_ctx;
 #  define archive_rmd160_init(ctx)             RMD160Init(ctx)
 #  define archive_rmd160_final(ctx, buf)       RMD160Final(buf, ctx)
 #  define archive_rmd160_update(ctx, buf, n)   RMD160Update(ctx, buf, n)
-#elif defined(HAVE_OPENSSL_RIPEMD_H)
+#elif defined(ARCHIVE_HASH_RMD160_OPENSSL)
 #  include <openssl/ripemd.h>
 #  define ARCHIVE_HAS_RMD160
 typedef RIPEMD160_CTX archive_rmd160_ctx;
@@ -86,21 +90,21 @@ typedef RIPEMD160_CTX archive_rmd160_ctx;
 #  define archive_rmd160_update(ctx, buf, n)   RIPEMD160_Update(ctx, buf, n)
 #endif
 
-#if defined(HAVE_SHA1_H) && defined(HAVE_SHA1INIT)
+#if defined(ARCHIVE_HASH_SHA1_LIBC)
 #  include <sha1.h>
 #  define ARCHIVE_HAS_SHA1
 typedef SHA1_CTX archive_sha1_ctx;
 #  define archive_sha1_init(ctx)               SHA1Init(ctx)
 #  define archive_sha1_final(ctx, buf)         SHA1Final(buf, ctx)
 #  define archive_sha1_update(ctx, buf, n)     SHA1Update(ctx, buf, n)
-#elif defined(HAVE_OPENSSL_SHA_H)
+#elif defined(ARCHIVE_HASH_SHA1_OPENSSL)
 #  include <openssl/sha.h>
 #  define ARCHIVE_HAS_SHA1
 typedef SHA_CTX archive_sha1_ctx;
 #  define archive_sha1_init(ctx)               SHA1_Init(ctx)
 #  define archive_sha1_final(ctx, buf)         SHA1_Final(buf, ctx)
 #  define archive_sha1_update(ctx, buf, n)     SHA1_Update(ctx, buf, n)
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(CALG_SHA1)
+#elif defined(ARCHIVE_HASH_SHA1_WIN)
 #  define ARCHIVE_HAS_SHA1
 typedef SHA1_CTX archive_sha1_ctx;
 #  define archive_sha1_init(ctx)               SHA1_Init(ctx)
@@ -108,28 +112,35 @@ typedef SHA1_CTX archive_sha1_ctx;
 #  define archive_sha1_update(ctx, buf, n)     SHA1_Update(ctx, buf, n)
 #endif
 
-#if defined(HAVE_SHA2_H) && defined(HAVE_SHA256_INIT)
+#if defined(ARCHIVE_HASH_SHA256_LIBC)
 #  include <sha2.h>
 #  define ARCHIVE_HAS_SHA256
 typedef SHA256_CTX archive_sha256_ctx;
 #  define archive_sha256_init(ctx)             SHA256_Init(ctx)
 #  define archive_sha256_final(ctx, buf)       SHA256_Final(buf, ctx)
 #  define archive_sha256_update(ctx, buf, n)   SHA256_Update(ctx, buf, n)
-#elif defined(HAVE_SHA2_H) && defined(HAVE_SHA256INIT)
+#elif defined(ARCHIVE_HASH_SHA256_LIBC2)
 #  include <sha2.h>
 #  define ARCHIVE_HAS_SHA256
 typedef SHA256_CTX archive_sha256_ctx;
 #  define archive_sha256_init(ctx)             SHA256Init(ctx)
 #  define archive_sha256_final(ctx, buf)       SHA256Final(buf, ctx)
 #  define archive_sha256_update(ctx, buf, n)   SHA256Update(ctx, buf, n)
-#elif defined(HAVE_OPENSSL_SHA_H) && defined(HAVE_OPENSSL_SHA256_INIT)
+#elif defined(ARCHIVE_HASH_SHA256_LIBC3)
+#  include <sha2.h>
+#  define ARCHIVE_HAS_SHA256
+typedef SHA2_CTX archive_sha256_ctx;
+#  define archive_sha256_init(ctx)             SHA256Init(ctx)
+#  define archive_sha256_final(ctx, buf)       SHA256Final(buf, ctx)
+#  define archive_sha256_update(ctx, buf, n)   SHA256Update(ctx, buf, n)
+#elif defined(ARCHIVE_HASH_SHA256_OPENSSL)
 #  include <openssl/sha.h>
 #  define ARCHIVE_HAS_SHA256
 typedef SHA256_CTX archive_sha256_ctx;
 #  define archive_sha256_init(ctx)             SHA256_Init(ctx)
 #  define archive_sha256_final(ctx, buf)       SHA256_Final(buf, ctx)
 #  define archive_sha256_update(ctx, buf, n)   SHA256_Update(ctx, buf, n)
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(CALG_SHA_256)
+#elif defined(ARCHIVE_HASH_SHA256_WIN)
 #  define ARCHIVE_HAS_SHA256
 typedef SHA256_CTX archive_sha256_ctx;
 #  define archive_sha256_init(ctx)             SHA256_Init(ctx)
@@ -137,28 +148,35 @@ typedef SHA256_CTX archive_sha256_ctx;
 #  define archive_sha256_update(ctx, buf, n)   SHA256_Update(ctx, buf, n)
 #endif
 
-#if defined(HAVE_SHA2_H) && defined(HAVE_SHA384_INIT)
+#if defined(ARCHIVE_HASH_SHA384_LIBC)
 #  include <sha2.h>
 #  define ARCHIVE_HAS_SHA384
 typedef SHA384_CTX archive_sha384_ctx;
 #  define archive_sha384_init(ctx)             SHA384_Init(ctx)
 #  define archive_sha384_final(ctx, buf)       SHA384_Final(buf, ctx)
 #  define archive_sha384_update(ctx, buf, n)   SHA384_Update(ctx, buf, n)
-#elif defined(HAVE_SHA2_H) && defined(HAVE_SHA384INIT)
+#elif defined(ARCHIVE_HASH_SHA384_LIBC2)
 #  include <sha2.h>
 #  define ARCHIVE_HAS_SHA384
 typedef SHA384_CTX archive_sha384_ctx;
 #  define archive_sha384_init(ctx)             SHA384Init(ctx)
 #  define archive_sha384_final(ctx, buf)       SHA384Final(buf, ctx)
 #  define archive_sha384_update(ctx, buf, n)   SHA384Update(ctx, buf, n)
-#elif defined(HAVE_OPENSSL_SHA_H) && defined(HAVE_OPENSSL_SHA384_INIT)
+#elif defined(ARCHIVE_HASH_SHA384_LIBC3)
+#  include <sha2.h>
+#  define ARCHIVE_HAS_SHA384
+typedef SHA2_CTX archive_sha384_ctx;
+#  define archive_sha384_init(ctx)             SHA384Init(ctx)
+#  define archive_sha384_final(ctx, buf)       SHA384Final(buf, ctx)
+#  define archive_sha384_update(ctx, buf, n)   SHA384Update(ctx, buf, n)
+#elif defined(ARCHIVE_HASH_SHA384_OPENSSL)
 #  include <openssl/sha.h>
 #  define ARCHIVE_HAS_SHA384
 typedef SHA512_CTX archive_sha384_ctx;
 #  define archive_sha384_init(ctx)             SHA384_Init(ctx)
 #  define archive_sha384_final(ctx, buf)       SHA384_Final(buf, ctx)
 #  define archive_sha384_update(ctx, buf, n)   SHA384_Update(ctx, buf, n)
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(CALG_SHA_384)
+#elif defined(ARCHIVE_HASH_SHA384_WIN)
 #  define ARCHIVE_HAS_SHA384
 typedef SHA512_CTX archive_sha384_ctx;
 #  define archive_sha384_init(ctx)             SHA384_Init(ctx)
@@ -166,28 +184,35 @@ typedef SHA512_CTX archive_sha384_ctx;
 #  define archive_sha384_update(ctx, buf, n)   SHA384_Update(ctx, buf, n)
 #endif
 
-#if defined(HAVE_SHA2_H) && defined(HAVE_SHA512_INIT)
+#if defined(ARCHIVE_HASH_SHA512_LIBC)
 #  include <sha2.h>
 #  define ARCHIVE_HAS_SHA512
 typedef SHA512_CTX archive_sha512_ctx;
 #  define archive_sha512_init(ctx)             SHA512_Init(ctx)
 #  define archive_sha512_final(ctx, buf)       SHA512_Final(buf, ctx)
 #  define archive_sha512_update(ctx, buf, n)   SHA512_Update(ctx, buf, n)
-#elif defined(HAVE_SHA2_H) && defined(HAVE_SHA512INIT)
+#elif defined(ARCHIVE_HASH_SHA512_LIBC2)
 #  include <sha2.h>
 #  define ARCHIVE_HAS_SHA512
 typedef SHA512_CTX archive_sha512_ctx;
 #  define archive_sha512_init(ctx)             SHA512Init(ctx)
 #  define archive_sha512_final(ctx, buf)       SHA512Final(buf, ctx)
 #  define archive_sha512_update(ctx, buf, n)   SHA512Update(ctx, buf, n)
-#elif defined(HAVE_OPENSSL_SHA_H) && defined(HAVE_OPENSSL_SHA512_INIT)
+#elif defined(ARCHIVE_HASH_SHA512_LIBC3)
+#  include <sha2.h>
+#  define ARCHIVE_HAS_SHA512
+typedef SHA2_CTX archive_sha512_ctx;
+#  define archive_sha512_init(ctx)             SHA512Init(ctx)
+#  define archive_sha512_final(ctx, buf)       SHA512Final(buf, ctx)
+#  define archive_sha512_update(ctx, buf, n)   SHA512Update(ctx, buf, n)
+#elif defined(ARCHIVE_HASH_SHA512_OPENSSL)
 #  include <openssl/sha.h>
 #  define ARCHIVE_HAS_SHA512
 typedef SHA512_CTX archive_sha512_ctx;
 #  define archive_sha512_init(ctx)             SHA512_Init(ctx)
 #  define archive_sha512_final(ctx, buf)       SHA512_Final(buf, ctx)
 #  define archive_sha512_update(ctx, buf, n)   SHA512_Update(ctx, buf, n)
-#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(CALG_SHA_512)
+#elif defined(ARCHIVE_HASH_SHA512_WIN)
 #  define ARCHIVE_HAS_SHA512
 typedef SHA512_CTX archive_sha512_ctx;
 #  define archive_sha512_init(ctx)             SHA512_Init(ctx)