dnl ProFTPD - mod_proxy
dnl Copyright (c) 2012-2022 TJ Saunders <tj@castaglia.org>
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
dnl
dnl Process this file with autoconf to produce a configure script.

AC_INIT(./mod_proxy.c)

AC_CANONICAL_SYSTEM

ostype=`echo $build_os | sed 's/\..*$//g' | sed 's/-.*//g' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`

AC_PROG_CC
AC_PROG_CPP
AC_AIX
AC_ISC_POSIX
AC_MINIX
AC_PROG_MAKE_SET

dnl Need to support/handle the --with-includes, --with-libraries, --enable-tests
dnl options
AC_ARG_WITH(includes,
  [AC_HELP_STRING(
    [--with-includes=LIST],
    [add additional include paths to proftpd. LIST is a colon-separated list of include paths to add e.g. --with-includes=/some/mysql/include:/my/include])
  ],
  [ ac_addl_includes=`echo "$withval" | sed -e 's/:/ /g'` ;
    for ainclude in $ac_addl_includes; do
      if test x"$ac_build_addl_includes" = x ; then
        ac_build_addl_includes="-I$ainclude"
      else
        ac_build_addl_includes="-I$ainclude $ac_build_addl_includes"
      fi
    done
    CPPFLAGS="$CPPFLAGS $ac_build_addl_includes"
  ])

AC_ARG_WITH(libraries,
  [AC_HELP_STRING(
    [--with-libraries=LIST],
    [add additional library paths to proftpd. LIST is a colon-separated list of include paths to add e.g. --with-libraries=/some/mysql/libdir:/my/libs])
  ],
  [ ac_addl_libdirs=`echo "$withval" | sed -e 's/:/ /g'` ;
    for alibdir in $ac_addl_libdirs; do
      if test x"$ac_build_addl_libdirs" = x ; then
        ac_build_addl_libdirs="-L$alibdir"
      else
        ac_build_addl_libdirs="-L$alibdir $ac_build_addl_libdirs"
      fi
    done
    LDFLAGS="$LDFLAGS $ac_build_addl_libdirs"
  ])

ENABLE_TESTS="\"\""
AC_ARG_ENABLE(tests,
  [AC_HELP_STRING(
    [--enable-tests],
    [enable unit tests (default=no)])
  ],
  [
    if test x"$enableval" != xno ; then
      AC_CHECK_HEADERS(check.h)

      AC_CHECK_LIB(check, tcase_create,
        [AC_DEFINE(HAVE_LIBCHECK, 1, [Define if libcheck is present.])
         ENABLE_TESTS="1"
        ],
        [
         AC_MSG_ERROR([libcheck support, required for tests, not present -- aborting])
        ]
      )
    fi
  ])

AC_HEADER_STDC
AC_CHECK_HEADERS(sqlite3.h stdlib.h unistd.h limits.h fcntl.h sys/sysctl.h sys/sysinfo.h)
AC_CHECK_HEADER(zlib.h,
  [AC_DEFINE(HAVE_ZLIB_H, 1, [Define if zlib.h is present.])
   MODULE_LIBS="$MODULE_LIBS -lz"
  ])
AC_CHECK_FUNCS(random srandom strnstr sysctl sysinfo)

dnl Check whether libc provides the DNS resolver symbols (e.g. *BSD/Mac OSX)
dnl or not.  And if not, check whether we need to link directly with
dnl /usr/lib/libresolv.a (32-bit) or /usr/lib64/libresolv.a (64-bit).
dnl
dnl Ideally we would link with libresolv using -lresolv.  However, it seems
dnl that many Linux distributions shipped a broken version of libresolv.so
dnl which did not export the necessary ns_initparse/ns_parserr symbols.  The
dnl static version of libresolv shipped DOES provide those symbols (probably
dnl for use by libc).  For these cases, we link againt the static library.

ac_dns_libs=""
AC_MSG_CHECKING([for resolver symbols in libc])
AC_TRY_LINK(
  [ #include <stdlib.h>
    #include <sys/types.h>
    #include <arpa/nameser.h>
    #include <resolv.h>
  ],
  [
    int res;
    res = res_query(NULL, ns_c_in, ns_t_txt, NULL, 0);
    res = ns_initparse(NULL, 0, NULL);
    res = ns_parserr(NULL, ns_s_an, 0, NULL);
  ],
  [
    AC_MSG_RESULT(yes)
  ],
  [
    AC_MSG_RESULT(no)

    AC_MSG_CHECKING([for resolver symbols in libresolv])
    saved_libs="$LIBS"
    LIBS="$LIBS -lresolv"

    AC_TRY_LINK(
      [ #include <stdlib.h>
        #include <sys/types.h>
        #include <arpa/nameser.h>
        #include <resolv.h>
      ],
      [
        int res;
        res = res_query(NULL, ns_c_in, ns_t_txt, NULL, 0);
        res = ns_initparse(NULL, 0, NULL);
        res = ns_parserr(NULL, ns_s_an, 0, NULL);
      ],
      [
        AC_MSG_RESULT(yes)
        LIBS="$saved_libs"
        ac_dns_libs="-lresolv"
      ],
      [
        AC_MSG_RESULT(no)
        LIBS="$saved_libs"

        AC_MSG_CHECKING([for resolver symbols in /usr/lib64/libresolv.a])
        saved_libs="$LIBS"
        LIBS="$LIBS /usr/lib64/libresolv.a"

        AC_TRY_LINK(
          [ #include <stdlib.h>
            #include <sys/types.h>
            #include <arpa/nameser.h>
            #include <resolv.h>
          ],
          [
            int res;
            res = res_query(NULL, ns_c_in, ns_t_txt, NULL, 0);
            res = ns_initparse(NULL, 0, NULL);
            res = ns_parserr(NULL, ns_s_an, 0, NULL);
          ],
          [
            AC_MSG_RESULT(yes)
            LIBS="$saved_libs"
            ac_dns_libs="/usr/lib64/libresolv.a"
          ],
          [
             AC_MSG_RESULT(no)
             LIBS="$saved_libs"

            AC_MSG_CHECKING([for resolver symbols in /usr/lib/libresolv.a])
            saved_libs="$LIBS"
            LIBS="$LIBS /usr/lib/libresolv.a"

            AC_TRY_LINK(
              [ #include <stdlib.h>
                #include <sys/types.h>
                #include <arpa/nameser.h>
                #include <resolv.h>
              ],
              [
                int res;
                res = res_query(NULL, ns_c_in, ns_t_txt, NULL, 0);
                res = ns_initparse(NULL, 0, NULL);
                res = ns_parserr(NULL, ns_s_an, 0, NULL);
              ],
              [
                AC_MSG_RESULT(yes)
                LIBS="$saved_libs"
                ac_dns_libs="/usr/lib/libresolv.a"
              ],
              [
                AC_MSG_RESULT(no)
                LIBS="$saved_libs"
              ]
            )
          ]
        )
      ]
    )
  ]
)

# Check for OpenSSL-isms
AC_MSG_CHECKING([whether OpenSSL has crippled AES support])
LIBS="-lcrypto $LIBS"

AC_TRY_LINK(
  [ #ifdef HAVE_STRING_H
    # include <string.h>
    #endif
    #include <openssl/evp.h>
  ],
  [
    EVP_CIPHER *c;
    c = EVP_aes_192_cbc();
    c = EVP_aes_256_cbc();
  ],
  [
    AC_MSG_RESULT(no)
    LIBS="$saved_libs"
  ],
  [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_AES_CRIPPLED_OPENSSL, 1, [OpenSSL is missing AES192 and AES256 support])
    LIBS="$saved_libs"
  ]
)

AC_MSG_CHECKING([whether OpenSSL supports SHA256])
LIBS="-lcrypto $LIBS"

AC_TRY_LINK(
  [
    #include <openssl/evp.h>
  ],
  [
    const EVP_MD *md;
    md = EVP_sha256();
  ],
  [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_SHA256_OPENSSL, 1, [OpenSSL supports SHA224/SHA256])
    LIBS="$saved_libs"
  ],
  [
    AC_MSG_RESULT(no)
    LIBS="$saved_libs"
  ]
)

AC_MSG_CHECKING([whether OpenSSL supports SHA512])
LIBS="-lcrypto $LIBS"

AC_TRY_LINK(
  [
    #include <openssl/evp.h>
  ],
  [
    const EVP_MD *md;
    md = EVP_sha512();
  ],
  [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_SHA512_OPENSSL, 1, [OpenSSL supports SHA384/SHA512])
    LIBS="$saved_libs"
  ],
  [
    AC_MSG_RESULT(no)
    LIBS="$saved_libs"
  ]
)

AC_MSG_CHECKING([whether OpenSSL supports EVP_aes_128_ctr])
LIBS="-lcrypto $LIBS"

AC_TRY_LINK(
  [
    #include <openssl/evp.h>
  ],
  [
    EVP_CIPHER *cipher;
    cipher = EVP_aes_128_ctr();
  ],
  [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_EVP_AES_128_CTR_OPENSSL, 1, [OpenSSL supports EVP_aes_128_ctr])
    LIBS="$saved_libs"
  ],
  [
    AC_MSG_RESULT(no)
    LIBS="$saved_libs"
  ]
)

AC_MSG_CHECKING([whether OpenSSL supports EVP_aes_192_ctr])
LIBS="-lcrypto $LIBS"

AC_TRY_LINK(
  [
    #include <openssl/evp.h>
  ],
  [
    EVP_CIPHER *cipher;
    cipher = EVP_aes_192_ctr();
  ],
  [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_EVP_AES_192_CTR_OPENSSL, 1, [OpenSSL supports EVP_aes_192_ctr])
    LIBS="$saved_libs"
  ],
  [
    AC_MSG_RESULT(no)
    LIBS="$saved_libs"
  ]
)

AC_MSG_CHECKING([whether OpenSSL supports EVP_aes_256_ctr])
LIBS="-lcrypto $LIBS"

AC_TRY_LINK(
  [
    #include <openssl/evp.h>
  ],
  [
    EVP_CIPHER *cipher;
    cipher = EVP_aes_256_ctr();
  ],
  [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_EVP_AES_256_CTR_OPENSSL, 1, [OpenSSL supports EVP_aes_256_ctr])
    LIBS="$saved_libs"
  ],
  [
    AC_MSG_RESULT(no)
    LIBS="$saved_libs"
  ]
)

AC_MSG_CHECKING([whether OpenSSL supports EVP_aes_256_gcm])
LIBS="-lcrypto $LIBS"

AC_TRY_LINK(
  [
    #include <openssl/evp.h>
  ],
  [
    EVP_CIPHER *cipher;
    cipher = EVP_aes_256_gcm();
  ],
  [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_EVP_AES_256_GCM_OPENSSL, 1, [OpenSSL supports EVP_aes_256_gcm])
    LIBS="$saved_libs"
  ],
  [
    AC_MSG_RESULT(no)
    LIBS="$saved_libs"
  ]
)

AC_MSG_CHECKING([whether OpenSSL supports X448 algorithm])
LIBS="-lcrypto $LIBS"

AC_TRY_LINK(
  [
    #include <openssl/evp.h>
  ],
  [
    EVP_PKEY *pkey;
    EVP_PKEY_CTX *pctx;

    pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X448, NULL, NULL, 0);
    pctx = EVP_PKEY_CTX_new_id(NID_X448, NULL);
  ],
  [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_X448_OPENSSL, 1, [OpenSSL supports X448 algorithm])
    LIBS="$saved_libs"
  ],
  [
    AC_MSG_RESULT(no)
    LIBS="$saved_libs"
  ]
)

AC_MSG_CHECKING([whether OpenSSL supports OSSL_PROVIDER_load])
LIBS="-lcrypto $LIBS"

AC_TRY_LINK(
  [
    #include <openssl/provider.h>
  ],
  [
    OSSL_PROVIDER *provider;
    provider = OSSL_PROVIDER_load(NULL, "default");
  ],
  [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_OSSL_PROVIDER_LOAD_OPENSSL, 1, [OpenSSL supports OSSL_PROVIDER_load])
    LIBS="$saved_libs"
  ],
  [
    AC_MSG_RESULT(no)
    LIBS="$saved_libs"
  ]
)

# Check for SQLite-isms
AC_MSG_CHECKING([for sqlite3_stmt_readonly])
saved_libs="$LIBS"
LIBS="-lsqlite3"
AC_TRY_LINK([
    #include <stdlib.h>
    #include <sys/types.h>
    #ifdef HAVE_SQLITE3_H
    # include <sqlite3.h>
    #endif
  ], [
    (void) sqlite3_stmt_readonly(NULL);
  ], [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_SQLITE3_STMT_READONLY, 1, [Define if you have the sqlite3_stmt_readonly function])
  ], [
    AC_MSG_RESULT(no)
  ]
)
LIBS="$saved_libs"

AC_MSG_CHECKING([for sqlite3_trace])
saved_libs="$LIBS"
LIBS="-lsqlite3"
AC_TRY_LINK([
    #include <stdlib.h>
    #include <sys/types.h>
    #ifdef HAVE_SQLITE3_H
    # include <sqlite3.h>
    #endif
  ], [
    (void) sqlite3_trace(NULL, NULL, NULL);
  ], [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_SQLITE3_TRACE, 1, [Define if you have the sqlite3_trace function])
  ], [
    AC_MSG_RESULT(no)
  ]
)
LIBS="$saved_libs"

AC_MSG_CHECKING([for sqlite3_trace_v2])
saved_libs="$LIBS"
LIBS="-lsqlite3"
AC_TRY_LINK([
    #include <stdlib.h>
    #include <sys/types.h>
    #ifdef HAVE_SQLITE3_H
    # include <sqlite3.h>
    #endif
  ], [
    (void) sqlite3_trace_v2(NULL, 0, NULL, NULL);
  ], [
    AC_MSG_RESULT(yes)
    AC_DEFINE(HAVE_SQLITE3_TRACE_V2, 1, [Define if you have the sqlite3_trace_v2 function])
  ], [
    AC_MSG_RESULT(no)
  ]
)
LIBS="$saved_libs"

INCLUDES="$ac_build_addl_includes"
LIBDIRS="$ac_build_addl_libdirs"
MODULE_LIBS="$MODULE_LIBS $ac_dns_libs"

AC_SUBST(ENABLE_TESTS)
AC_SUBST(INCLUDES)
AC_SUBST(LDFLAGS)
AC_SUBST(LIBDIRS)
AC_SUBST(MODULE_LIBS)

AC_CONFIG_HEADER(mod_proxy.h)
AC_OUTPUT(
  t/Makefile
  Makefile
)
