mirror of
https://github.com/Cacti/spine.git
synced 2026-10-23 03:27:10 +09:00
The runtime/probe changes from #642 and GNU C17/build changes from #643 were squash-merged into #641's source branch, which made the result-normalization review include later stages. This follow-up preserves those approved changes while restoring #641's focused diff against develop. No force-push or approved-code deletion is required. Merge after #641 and before #644. #644 will target this branch. This combines the already reviewed steps 5 and 6; it introduces no new worker-stack or module-extraction changes. The UDP follow-up also corrects a validated finding: EHOSTUNREACH on a connected socket is ambiguous and can represent an unreachable host or failed neighbour lookup. It now reports down; ECONNREFUSED/ECONNRESET and actual peer datagrams retain their existing alive behavior. The production-linked test rejects the original EHOSTUNREACH behavior. Validation: Ubuntu 24.04/aarch64, clean GCC build and make check: 17 passed, one existing setuid prerequisite skip, zero failures. The full tracked source tree is byte-identical to the independently validated #641 functional-fix snapshot. The UDP and poll-host regressions fail against the original code and pass after the fixes. The isolated step-4 tree independently passes 15 tests with one existing skip. No live endpoints, host installation, privilege changes, or test suppression. Repository squash merges still require restacking/retargeting the next child after each merge; clean ordinary merge simulations are insufficient by themselves. --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
733 lines
26 KiB
Plaintext
733 lines
26 KiB
Plaintext
# +-------------------------------------------------------------------------+
|
|
# | Copyright (C) 2004-2026 The Cacti Group |
|
|
# | |
|
|
# | 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 |
|
|
# | 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. |
|
|
# +-------------------------------------------------------------------------+
|
|
# | Cacti: The Complete RRDtool-based Graphing Solution |
|
|
# +-------------------------------------------------------------------------+
|
|
# | This code is designed, written, and maintained by the Cacti Group. See |
|
|
# | about.php and/or the AUTHORS file for specific developer information. |
|
|
# +-------------------------------------------------------------------------+
|
|
# | http://www.cacti.net/ |
|
|
# +-------------------------------------------------------------------------+
|
|
|
|
AC_PREREQ([2.69])
|
|
AC_INIT([Spine Poller],[1.3.0],[http://www.cacti.net/issues.php])
|
|
|
|
AC_CONFIG_AUX_DIR(config)
|
|
AC_SUBST(ac_aux_dir)
|
|
|
|
AC_CANONICAL_HOST
|
|
AC_CONFIG_SRCDIR(spine.c)
|
|
AC_PREFIX_DEFAULT(/usr/local/spine)
|
|
AC_LANG(C)
|
|
|
|
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
|
AM_SILENT_RULES([yes])
|
|
AC_CONFIG_HEADERS(config/config.h)
|
|
|
|
# These generic package macros belong to the generated configuration header.
|
|
# Leave them available for Net-SNMP to define; snmp_spine_init uses its
|
|
# PACKAGE_VERSION when header/library version verification is enabled.
|
|
# Continue each directive so config.status preserves the literal cleanup
|
|
# instead of substituting another package definition into the header footer.
|
|
AH_BOTTOM([#undef \
|
|
PACKAGE_NAME
|
|
#undef \
|
|
PACKAGE_VERSION
|
|
#undef \
|
|
PACKAGE_BUGREPORT
|
|
#undef \
|
|
PACKAGE_STRING
|
|
#undef \
|
|
PACKAGE_TARNAME])
|
|
|
|
# static libraries
|
|
AC_ARG_WITH(static,
|
|
AS_HELP_STRING([--with-static],[Build using static libraries
|
|
]),
|
|
[CFLAGS="-static $CFLAGS"]
|
|
)
|
|
|
|
AC_CONFIG_MACRO_DIR([m4])
|
|
|
|
# mysql
|
|
AC_ARG_WITH(mysql,
|
|
AS_HELP_STRING([--with-mysql],[MySQL base directory [[/usr/local/mysql]]
|
|
]),
|
|
[MYSQL_DIR=$withval]
|
|
)
|
|
|
|
# snmp
|
|
AC_ARG_WITH(snmp,
|
|
AS_HELP_STRING([--with-snmp],[SNMP base directory [[/usr/(local/)include]]
|
|
]),
|
|
[SNMP_DIR=$withval]
|
|
)
|
|
|
|
# Platform-specific tweaks
|
|
ShLib="so"
|
|
|
|
case $host in
|
|
*sparc-sun-solaris2.8)
|
|
CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
|
|
AC_DEFINE(SOLAR_THREAD, 1, [Correct issue around Solaris threading model]);;
|
|
*solaris*)
|
|
CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS";;
|
|
*freebsd*)
|
|
LIBS="$LIBS -pthread -lexecinfo"
|
|
AC_DEFINE(HAVE_LIBPTHREAD, 1);;
|
|
*darwin*)
|
|
ShLib="dylib";;
|
|
*)
|
|
LIBS="-lpthread -lssl $LIBS"
|
|
esac
|
|
|
|
# Checks for programs.
|
|
AC_PROG_AWK
|
|
spine_user_cc=$CC
|
|
AC_PROG_CC
|
|
|
|
# ****************** C language standard ***********************
|
|
dnl Spine is written to C17 with GNU extensions (docs/adr/0001). Name it
|
|
dnl explicitly: the compiler default drifts, and GCC 15 moved it to gnu23.
|
|
dnl Autoconf 2.70 and later append their own -std to CC, overriding one the
|
|
dnl caller put there, so drop it. A -std in the caller's CC or CFLAGS wins.
|
|
if test -n "$spine_user_cc"; then
|
|
CC=$spine_user_cc
|
|
else
|
|
CC=`echo "$CC" | sed 's/ -std=[[^ ]]*//g'`
|
|
fi
|
|
spine_user_std=
|
|
for spine_flag in $spine_user_cc $CFLAGS; do
|
|
case $spine_flag in
|
|
-std=*) spine_user_std=$spine_flag ;;
|
|
esac
|
|
done
|
|
|
|
if test -z "$spine_user_std"; then
|
|
AC_MSG_CHECKING([whether $CC accepts -std=gnu17])
|
|
CFLAGS="$CFLAGS -std=gnu17"
|
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
|
|
[AC_MSG_RESULT([yes])],
|
|
[AC_MSG_RESULT([no])
|
|
AC_MSG_ERROR([$CC does not accept -std=gnu17. Spine needs a C17 compiler: GCC 8, Clang 6 or newer.])])
|
|
fi
|
|
|
|
AC_MSG_CHECKING([whether the compiler is in C17 mode or later])
|
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201710L
|
|
#error older than C17
|
|
#endif
|
|
]], [])],
|
|
[AC_MSG_RESULT([yes])],
|
|
[AC_MSG_RESULT([no])
|
|
if test -n "$spine_user_std"; then
|
|
AC_MSG_WARN([$spine_user_std selects a standard older than C17; Spine is developed and tested as gnu17])
|
|
else
|
|
AC_MSG_ERROR([__STDC_VERSION__ is below 201710L under -std=gnu17])
|
|
fi])
|
|
|
|
AC_PROG_CPP
|
|
AC_PROG_INSTALL
|
|
AC_PROG_LN_S
|
|
LT_INIT
|
|
|
|
AC_MSG_CHECKING([whether to enable -Wall])
|
|
AC_ARG_ENABLE(warnings,
|
|
[ --enable-warnings Enable -Wall if using gcc.],
|
|
[if test -n "$GCC"; then
|
|
AC_MSG_RESULT(adding -Wall to CFLAGS.)
|
|
CFLAGS="$CFLAGS -Wall"
|
|
fi
|
|
],
|
|
AC_MSG_RESULT(no)
|
|
)
|
|
|
|
AC_ARG_ENABLE(sanitizers,
|
|
[ --enable-sanitizers Build with AddressSanitizer and UndefinedBehaviorSanitizer.],
|
|
[if test "x$enableval" = "xyes"; then
|
|
AC_MSG_RESULT(adding -fsanitize=address,undefined to CFLAGS.)
|
|
CFLAGS="$CFLAGS -fsanitize=address,undefined -fno-omit-frame-pointer -g"
|
|
LDFLAGS="$LDFLAGS -fsanitize=address,undefined"
|
|
fi
|
|
],
|
|
AC_MSG_RESULT(no)
|
|
)
|
|
|
|
AC_PATH_PROG(HELP2MAN, help2man, false // No help2man //)
|
|
AC_CHECK_PROG([HELP2MAN], [help2man], [help2man])
|
|
AM_CONDITIONAL([HAVE_HELP2MAN], [test x$HELP2MAN = xhelp2man])
|
|
|
|
# Checks for libraries.
|
|
AC_CHECK_LIB(socket, socket)
|
|
AC_CHECK_LIB(m, floor)
|
|
AC_CHECK_LIB(dl, dlclose)
|
|
AC_CHECK_LIB(pthread, pthread_exit)
|
|
|
|
# Some builds of MySQL require libz - try to detect
|
|
AC_CHECK_LIB(z, deflate)
|
|
AC_CHECK_LIB(kstat, kstat_close)
|
|
AC_CHECK_LIB(crypto, CRYPTO_realloc)
|
|
|
|
# minor adjustments for debian
|
|
AC_SEARCH_LIBS([clock_gettime], [rt pthread])
|
|
|
|
# Checks for header files.
|
|
AC_CHECK_HEADERS(sys/socket.h sys/select.h sys/wait.h sys/time.h)
|
|
AC_CHECK_HEADERS(assert.h ctype.h errno.h signal.h math.h malloc.h netdb.h)
|
|
AC_CHECK_HEADERS(signal.h stdarg.h stdio.h syslog.h)
|
|
AC_CHECK_HEADERS(ifaddrs.h net/if.h)
|
|
AC_CHECK_HEADERS(
|
|
netinet/in_systm.h netinet/in.h netinet/ip.h netinet/ip_icmp.h,
|
|
[],
|
|
[],
|
|
[#ifdef HAVE_SYS_TYPES_H
|
|
#include <sys/types.h>
|
|
#endif
|
|
#ifdef HAVE_NETINET_IN_H
|
|
#include <netinet/in.h>
|
|
#endif
|
|
#ifdef HAVE_NETINET_IN_SYSTM_H
|
|
#include <netinet/in_systm.h>
|
|
#endif
|
|
#ifdef HAVE_NETINET_IP_H
|
|
#include <netinet/ip.h>
|
|
#endif]
|
|
)
|
|
|
|
# Checks for typedefs, structures, and compiler characteristics.
|
|
AC_CHECK_TYPES([unsigned long long, long long])
|
|
AC_TYPE_SIZE_T
|
|
|
|
# Checks for library functions.
|
|
AC_CHECK_FUNCS(malloc calloc gettimeofday strerror strtoll getifaddrs if_nametoindex)
|
|
|
|
# ****************** Solaris Privileges Check ***********************
|
|
|
|
# Check if usage of Solaris privileges support is possible
|
|
AC_CHECK_HEADER(priv.h, [FOUND_PRIV_H=yes], [FOUND_PRIV_H=no])
|
|
|
|
# If we should use the Solaris privileges support
|
|
AC_MSG_CHECKING(whether we are using Solaris privileges)
|
|
AC_ARG_ENABLE(solaris-priv,
|
|
[ --enable-solaris-priv Enable support for the Solaris process privilege model (default: disabled)],
|
|
[ ENABLED_SOL_PRIV=$enableval ],
|
|
[ ENABLED_SOL_PRIV=no ]
|
|
)
|
|
if test x$ENABLED_SOL_PRIV != xno; then
|
|
if test x$FOUND_PRIV_H != xno; then
|
|
AC_MSG_RESULT([yes])
|
|
AC_DEFINE([SOLAR_PRIV], [1],
|
|
[If Support for Solaris privileges should be enabled]
|
|
)
|
|
else
|
|
AC_MSG_RESULT([no])
|
|
fi
|
|
else
|
|
AC_MSG_RESULT([no])
|
|
fi
|
|
|
|
# ****************** Linux Capabilities Check ***********************
|
|
CAPLOC="sys/capability.h"
|
|
for file in sys/capability.h;do
|
|
test -f /usr/include/$file && CAPLOC=$file && break
|
|
done
|
|
|
|
AC_CHECK_HEADER($CAPLOC, [FOUND_SYS_CAPABILITY_H=yes],
|
|
[FOUND_SYS_CAPABILITY_H=no])
|
|
|
|
# If we should use the Linux Capabilities support
|
|
AC_MSG_CHECKING(whether we are using Linux Capabilities)
|
|
AC_ARG_ENABLE(lcap,
|
|
[ --enable-lcap Enable support for the Linux Capabilities (default: disabled)],
|
|
[ ENABLED_LCAP=$enableval ],
|
|
[ ENABLED_LCAP=no ]
|
|
)
|
|
|
|
HAVE_LCAP=no
|
|
if test x$ENABLED_LCAP != xno; then
|
|
AC_MSG_RESULT([yes])
|
|
if test x$FOUND_SYS_CAPABILITY_H != xno; then
|
|
AC_CHECK_LIB(cap, cap_init,
|
|
[ LIBS="-lcap $LIBS"
|
|
AC_DEFINE(HAVE_LCAP, 1, Linux Capabilities)
|
|
HAVE_LCAP=yes ])
|
|
fi
|
|
# An explicit request must not quietly produce a build without it.
|
|
if test x$HAVE_LCAP != xyes; then
|
|
AC_MSG_ERROR([--enable-lcap was given but libcap (sys/capability.h and -lcap) was not found])
|
|
fi
|
|
else
|
|
AC_MSG_RESULT([no])
|
|
if test x$FOUND_SYS_CAPABILITY_H != xno; then
|
|
AC_MSG_NOTICE([libcap headers were found but are not used; pass --enable-lcap to use them])
|
|
else
|
|
AC_MSG_NOTICE([libcap was not found; building without Linux capabilities support])
|
|
fi
|
|
AC_MSG_NOTICE([without it a setuid root spine opens its raw ICMP sockets at startup, then drops root for good])
|
|
fi
|
|
|
|
# ****************** MySQL-compatible client checks ***********************
|
|
AC_ARG_VAR([MYSQL_CONFIG], [path to mariadb_config or mysql_config])
|
|
|
|
if test -n "$MYSQL_DIR" && test -z "$MYSQL_CONFIG"; then
|
|
for mysql_config_candidate in mariadb_config mysql_config; do
|
|
if test -x "$MYSQL_DIR/bin/$mysql_config_candidate"; then
|
|
MYSQL_CONFIG="$MYSQL_DIR/bin/$mysql_config_candidate"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if test -z "$MYSQL_CONFIG"; then
|
|
AC_PATH_PROGS([MYSQL_CONFIG], [mariadb_config mysql_config])
|
|
fi
|
|
|
|
if test -n "$MYSQL_CONFIG"; then
|
|
AC_MSG_NOTICE([using $MYSQL_CONFIG for database client flags])
|
|
if ! MYSQL_CFLAGS=`"$MYSQL_CONFIG" --cflags`; then
|
|
AC_MSG_ERROR([$MYSQL_CONFIG --cflags failed])
|
|
fi
|
|
if ! MYSQL_LIBS=`"$MYSQL_CONFIG" --libs`; then
|
|
AC_MSG_ERROR([$MYSQL_CONFIG --libs failed])
|
|
fi
|
|
CFLAGS="$MYSQL_CFLAGS $CFLAGS"
|
|
LIBS="$MYSQL_LIBS $LIBS"
|
|
else
|
|
AC_MSG_NOTICE([no client config tool found; using header and library discovery])
|
|
|
|
mysql_header_prefix=
|
|
|
|
for mysql_prefix in $MYSQL_DIR /usr /usr/local /opt /opt/mysql /usr/pkg /usr/local/mysql; do
|
|
for mysql_include_dir in include include/mysql include/mariadb mysql; do
|
|
if test -f "$mysql_prefix/$mysql_include_dir/mysql.h"; then
|
|
CFLAGS="-I$mysql_prefix/$mysql_include_dir $CFLAGS"
|
|
mysql_header_prefix=$mysql_prefix
|
|
break 2
|
|
fi
|
|
done
|
|
done
|
|
|
|
dnl The header can turn up under a prefix the caller never named, so search
|
|
dnl for the library under that same prefix. Adding only the MYSQL_DIR paths
|
|
dnl leaves mysql_init unlinkable when the client lives anywhere else.
|
|
mysql_library_prefixes="$MYSQL_DIR"
|
|
|
|
if test -n "$mysql_header_prefix" && test "x$mysql_header_prefix" != "x$MYSQL_DIR"; then
|
|
mysql_library_prefixes="$mysql_library_prefixes $mysql_header_prefix"
|
|
fi
|
|
|
|
for mysql_prefix in $mysql_library_prefixes; do
|
|
for mysql_library_dir in lib64 lib64/mysql lib lib/mysql; do
|
|
if test -d "$mysql_prefix/$mysql_library_dir"; then
|
|
LDFLAGS="-L$mysql_prefix/$mysql_library_dir $LDFLAGS"
|
|
fi
|
|
done
|
|
done
|
|
fi
|
|
|
|
AC_CHECK_HEADER([mysql.h], [],
|
|
[AC_MSG_ERROR([Cannot find mysql.h. Install MariaDB Connector/C or MySQL Connector/C development files.])])
|
|
|
|
AC_SEARCH_LIBS([mysql_init], [mariadb mysqlclient perconaserverclient],
|
|
[AC_DEFINE([HAVE_MYSQL], [1], [MySQL-compatible Client API])
|
|
HAVE_MYSQL=yes],
|
|
[AC_MSG_ERROR([Cannot link a MySQL-compatible client library.])])
|
|
|
|
# ****************** Net-SNMP Checks ***********************
|
|
if test "x$SNMP_DIR" != "x"; then
|
|
for i in / /net-snmp /include/net-snmp; do
|
|
test -f $SNMP_DIR/$i/net-snmp-config.h && SNMP_INCDIR=$SNMP_DIR$i && break
|
|
done
|
|
|
|
# Accommodate 64-Bit Libraries
|
|
test -f $SNMP_DIR/lib64/libnetsnmp.a -o -f $SNMP_DIR/lib64/libnetsnmp.$ShLib && SNMP_LIBDIR=$SNMP_DIR/lib64
|
|
|
|
if test -z "$SNMP_LIBDIR"; then
|
|
# Accommodate 32-Bit Libraries
|
|
test -f $SNMP_DIR/lib/libnetsnmp.a -o -f $SNMP_DIR/lib/libnetsnmp.$ShLib && SNMP_LIBDIR=$SNMP_DIR/lib
|
|
fi
|
|
else
|
|
for i in /usr /usr/local /usr/include /usr/pkg/include /usr/local/include /opt /opt/net-snmp /opt/snmp; do
|
|
test -f $i/snmp.h && SNMP_INCDIR=$i && break
|
|
test -f $i/include/net-snmp/net-snmp-config.h && SNMP_INCDIR=$i/include/net-snmp && break
|
|
test -f $i/net-snmp/net-snmp-config.h && SNMP_INCDIR=$i/net-snmp && break
|
|
test -f $i/net-snmp/include/net-snmp-config.h && SNMP_INCDIR=$i/net-snmp/include && break
|
|
test -f $i/snmp/snmp.h && SNMP_INCDIR=$i/snmp && break
|
|
test -f $i/snmp/include/net-snmp/net-snmp-config.h && SNMP_INCDIR=$i/snmp/include/net-snmp && break
|
|
done
|
|
|
|
# Accommodate 64-Bit Libraries
|
|
for i in /usr /usr/local /usr/pkg /usr/snmp /opt /opt/net-snmp /opt/snmp /usr/local/snmp; do
|
|
test -f $i/lib64/libnetsnmp.a -o -f $i/lib64/libnetsnmp.$ShLib && SNMP_LIBDIR=$i/lib64 && break
|
|
done
|
|
|
|
# Only check for 32 Bit libraries if the 64 bit are not found
|
|
if test -z "$SNMP_LIBDIR"; then
|
|
# Accommodate 32-Bit Libraries
|
|
for i in /usr /usr/local /usr/pkg /usr/snmp /opt /opt/net-snmp /opt/snmp /usr/local/snmp; do
|
|
test -f $i/lib/libnetsnmp.a -o -f $i/lib/libnetsnmp.$ShLib && SNMP_LIBDIR=$i/lib && break
|
|
done
|
|
fi
|
|
fi
|
|
|
|
if test -z "$SNMP_INCDIR"; then
|
|
if test "x$SNMP_DIR" != "x";then
|
|
AC_MSG_ERROR(Cannot find SNMP header files under $SNMP_DIR)
|
|
else
|
|
AC_MSG_ERROR(Cannot find SNMP headers. Use --with-snmp= to specify non-default path.)
|
|
fi
|
|
fi
|
|
|
|
if test -n "$SNMP_LIBDIR" ; then
|
|
LDFLAGS="-L$SNMP_LIBDIR $LDFLAGS"
|
|
fi
|
|
|
|
if test -n "$SNMP_INCDIR" ; then
|
|
CFLAGS="-I$SNMP_INCDIR -I$SNMP_INCDIR/.. $CFLAGS"
|
|
fi
|
|
|
|
# Net-SNMP includes v3 support and insists on crypto unless compiled --without-openssl
|
|
AC_MSG_CHECKING([if Net-SNMP needs crypto support])
|
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <net-snmp-config.h>]], [[return NETSNMP_USE_OPENSSL != 1;]])],
|
|
[ AC_MSG_RESULT(yes)
|
|
SNMP_SSL=yes
|
|
],[AC_MSG_RESULT(no)
|
|
])
|
|
|
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <net-snmp-config.h>
|
|
#include <net-snmp/utilities.h>
|
|
#include <net-snmp/net-snmp-includes.h>
|
|
#include <net-snmp/config_api.h>
|
|
#include <net-snmp/mib_api.h> ]], [[struct snmp_session session; snmp_sess_init(&session); session.localname = strdup("hello")]])],[havelocalname=1],[havelocalname=0
|
|
])
|
|
AC_DEFINE_UNQUOTED(SNMP_LOCALNAME, $havelocalname, If snmp localname session structure member exists)
|
|
|
|
AC_CHECK_LIB(netsnmp, snmp_timeout)
|
|
|
|
# ****************** Linker --wrap support (tests only) *********************
|
|
dnl The PHP runtime suite interposes on process and descriptor operations so
|
|
dnl destructive failure paths are deterministic. GNU ld and lld provide the
|
|
dnl required --wrap option; probe it so other supported linkers skip cleanly.
|
|
AC_MSG_CHECKING([whether the linker supports --wrap])
|
|
spine_save_LDFLAGS="$LDFLAGS"
|
|
LDFLAGS="$LDFLAGS -Wl,--wrap=spine_ld_wrap_probe"
|
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
|
int spine_ld_wrap_probe(void);
|
|
int __wrap_spine_ld_wrap_probe(void);
|
|
int __wrap_spine_ld_wrap_probe(void) { return 0; }
|
|
]], [[
|
|
return spine_ld_wrap_probe();
|
|
]])],
|
|
[spine_ld_wrap=yes],
|
|
[spine_ld_wrap=no])
|
|
LDFLAGS="$spine_save_LDFLAGS"
|
|
AC_MSG_RESULT($spine_ld_wrap)
|
|
AM_CONDITIONAL([HAVE_LD_WRAP], [test "x$spine_ld_wrap" = "xyes"])
|
|
|
|
# ****************** SNMPv3 USM Error Constants Check ***********************
|
|
AC_MSG_CHECKING([for SNMPv3 USM error constants])
|
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|
#include <net-snmp/net-snmp-config.h>
|
|
#include <net-snmp/net-snmp-includes.h>
|
|
]], [[
|
|
int x;
|
|
#if defined(SNMPERR_NOT_IN_TIME_WINDOW)
|
|
x = SNMPERR_NOT_IN_TIME_WINDOW;
|
|
#elif defined(SNMPERR_USM_NOTINTIMEWINDOW)
|
|
x = SNMPERR_USM_NOTINTIMEWINDOW;
|
|
#else
|
|
#error no USM error constants
|
|
#endif
|
|
(void)x;
|
|
]])],
|
|
[AC_MSG_RESULT([yes])],
|
|
[AC_MSG_RESULT([no (USM error decoding disabled)])]
|
|
)
|
|
|
|
# ****************** USM DES Privacy Protocol Symbol Check ***********************
|
|
# Some distributions (e.g. Fedora) ship a net-snmp-config.h that advertises DES
|
|
# as the default privacy protocol (SNMP_DEFAULT_PRIV_PROTO expands to
|
|
# usmDESPrivProtocol) while the shipped libnetsnmp does not export that symbol,
|
|
# so referencing the header's own default fails to link. Probe for the actual
|
|
# symbol rather than trusting the header.
|
|
AC_MSG_CHECKING([for usmDESPrivProtocol in libnetsnmp])
|
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
|
#include <net-snmp/net-snmp-config.h>
|
|
#include <net-snmp/net-snmp-includes.h>
|
|
]], [[
|
|
return usmDESPrivProtocol[0];
|
|
]])],
|
|
[AC_MSG_RESULT([yes])
|
|
AC_DEFINE(HAVE_USM_DES_PRIV_PROTOCOL, 1, [Define if libnetsnmp exports usmDESPrivProtocol])],
|
|
[AC_MSG_RESULT([no])]
|
|
)
|
|
|
|
# ****************** Spine Result Buffer Check ***********************
|
|
# Check for the default spine output buffer size
|
|
results_buffer=2048
|
|
AC_ARG_WITH(results-buffer,
|
|
AS_HELP_STRING([--with-results-buffer=N],[The size of the spine results buffer (default=2048)]),
|
|
[results_buffer=$withval]
|
|
)
|
|
AC_DEFINE_UNQUOTED(RESULTS_BUFFER, $results_buffer, The size of the spine result buffer)
|
|
AC_MSG_RESULT(checking for the spine results buffer size... $results_buffer bytes)
|
|
|
|
# ****************** Maximum Simultaneous Scripts ***********************
|
|
# Check for the most scripts that can be active at one time per spine process
|
|
max_scripts=20
|
|
AC_ARG_WITH(max-scripts,
|
|
AS_HELP_STRING([--with-max-scripts=N],[The maximum simultaneous spine scripts that can run (default=20)]),
|
|
[max_scripts=$withval]
|
|
)
|
|
AC_DEFINE_UNQUOTED(MAX_SIMULTANEOUS_SCRIPTS, $max_scripts, The maximum number of simultaneous running scripts)
|
|
AC_MSG_RESULT(checking for the maximum simultaneous spine scripts... $max_scripts)
|
|
|
|
# ****************** Maximum MySQL Buffer Size ***********************
|
|
# Check for the most scripts that can be active at one time per spine process
|
|
max_mysql_buffer=131072
|
|
AC_ARG_WITH(max-mysql-buffer,
|
|
AS_HELP_STRING([--with-max-mysql-buffer=N],[The maximum SQL insert size allowed (default=131072)]),
|
|
[max_mysql_buffer=$withval]
|
|
)
|
|
AC_DEFINE_UNQUOTED(MAX_MYSQL_BUF_SIZE, $max_mysql_buffer, The maximum MySQL buffer size to insert)
|
|
AC_MSG_RESULT(checking for the maximum MySQL buffer size... $max_mysql_buffer)
|
|
|
|
# ****************** Force Net-SNMP Version Checks ***********************
|
|
# If we should use the system popen or nifty popen
|
|
AC_MSG_CHECKING(whether to verify net-snmp library vs header versions)
|
|
AC_ARG_ENABLE(strict-snmp,
|
|
[ --enable-strict-snmp Enable checking of Net-SNMP library vs header versions (default: disabled)],
|
|
[ ENABLED_SNMP_VERSION=$enableval ],
|
|
[ ENABLED_SNMP_VERSION=no ]
|
|
)
|
|
if test "$ENABLED_SNMP_VERSION" = "yes"; then
|
|
AC_MSG_RESULT([yes])
|
|
AC_DEFINE(VERIFY_PACKAGE_VERSION, 1, If we are going to force Net-SNMP library and header versions to be the same)
|
|
else
|
|
AC_MSG_RESULT([no])
|
|
fi
|
|
|
|
AC_MSG_CHECKING([if we can support mysql/mariadb retry count])
|
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
|
#include <stdlib.h>
|
|
#include <mysql.h>
|
|
]], [[
|
|
if (MYSQL_OPT_RETRY_COUNT) {
|
|
exit(0);
|
|
} else {
|
|
exit(1);
|
|
}
|
|
]])],[ AC_MSG_RESULT(yes)
|
|
AC_DEFINE(HAS_MYSQL_OPT_RETRY_COUNT,1,[Do we have mysql/mariadb retry count capabilities?])
|
|
],[AC_MSG_RESULT(no)
|
|
])
|
|
|
|
AC_MSG_CHECKING([if we mysql/mariadb supports verify certificates])
|
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
|
#include <stdlib.h>
|
|
#include <mysql.h>
|
|
]], [[
|
|
if (MYSQL_OPT_SSL_VERIFY_SERVER_CERT) {
|
|
exit(0);
|
|
} else {
|
|
exit(1);
|
|
}
|
|
]])],[ AC_MSG_RESULT(yes)
|
|
AC_DEFINE(HAS_MYSQL_OPT_SSL_VERIFY_SERVER_CERT,1,[Do we have mysql/mariadb verify certificate support?])
|
|
],[AC_MSG_RESULT(no)
|
|
])
|
|
|
|
# See if we can support backtracing
|
|
AC_MSG_CHECKING([if we can support mysql/mariadb ssl keys])
|
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
|
#include <stdlib.h>
|
|
#include <mysql.h>
|
|
]], [[
|
|
if (MYSQL_OPT_SSL_KEY) {
|
|
exit(0);
|
|
} else {
|
|
exit(1);
|
|
}
|
|
]])],[ AC_MSG_RESULT(yes)
|
|
AC_DEFINE(HAS_MYSQL_OPT_SSL_KEY,1,[Do we have mysql/mariadb ssl keys capabilities?])
|
|
],[AC_MSG_RESULT(no)
|
|
])
|
|
|
|
spine_saved_ldflags=$LDFLAGS
|
|
spine_linker_wrap=no
|
|
case "$host_os" in
|
|
linux*)
|
|
LDFLAGS="$LDFLAGS -Wl,--wrap=strftime"
|
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
|
#include <time.h>
|
|
extern size_t __real_strftime(char *, size_t, const char *, const struct tm *);
|
|
size_t __wrap_strftime(char *out, size_t size, const char *format, const struct tm *time) {
|
|
return __real_strftime(out, size, format, time);
|
|
}
|
|
]], [[return 0;]])], [spine_linker_wrap=yes], [])
|
|
;;
|
|
*) ;;
|
|
esac
|
|
LDFLAGS=$spine_saved_ldflags
|
|
AM_CONDITIONAL([HAVE_LINKER_WRAP], [test "$spine_linker_wrap" = yes])
|
|
|
|
# ****************** Compiler and Linker Hardening ***********************
|
|
dnl Probe each flag with -Werror: clang only warns about options it ignores
|
|
dnl (-fstack-clash-protection and -pie on Darwin), and a warning would let the
|
|
dnl flag through without the protection. The accepted flags go in front of
|
|
dnl CPPFLAGS, CFLAGS and LDFLAGS so an explicit -fno-..., -no-pie or
|
|
dnl -U_FORTIFY_SOURCE from a packager or user still wins.
|
|
AC_ARG_ENABLE([hardening],
|
|
AS_HELP_STRING([--disable-hardening],[Do not add compiler and linker hardening flags (default: enabled)]),
|
|
[enable_hardening=$enableval],
|
|
[enable_hardening=yes])
|
|
|
|
AC_DEFUN([SPINE_HARDEN_CFLAG],
|
|
[AS_VAR_PUSHDEF([spine_cv], [spine_cv_harden_cflag_$1])dnl
|
|
AC_CACHE_CHECK([whether $CC accepts $1], [spine_cv],
|
|
[spine_save_CFLAGS=$CFLAGS
|
|
CFLAGS="$CFLAGS $1 -Werror"
|
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
|
|
[AS_VAR_SET([spine_cv], [yes])],
|
|
[AS_VAR_SET([spine_cv], [no])])
|
|
CFLAGS=$spine_save_CFLAGS])
|
|
AS_VAR_IF([spine_cv], [yes], [spine_hardening_cflags="$spine_hardening_cflags $1"])
|
|
AS_VAR_POPDEF([spine_cv])])
|
|
|
|
dnl Link probes run without LIBS: on Linux LIBS already names -lssl, and a
|
|
dnl missing library must not be mistaken for an unsupported linker flag.
|
|
AC_DEFUN([SPINE_HARDEN_LDFLAG],
|
|
[AS_VAR_PUSHDEF([spine_cv], [spine_cv_harden_ldflag_$1])dnl
|
|
AC_CACHE_CHECK([whether the linker accepts $1], [spine_cv],
|
|
[spine_save_CFLAGS=$CFLAGS
|
|
spine_save_LDFLAGS=$LDFLAGS
|
|
spine_save_LIBS=$LIBS
|
|
CFLAGS="$spine_hardening_cflags $CFLAGS -Werror"
|
|
LDFLAGS="$spine_hardening_ldflags $1 $LDFLAGS"
|
|
LIBS=
|
|
AC_LINK_IFELSE([AC_LANG_PROGRAM()],
|
|
[AS_VAR_SET([spine_cv], [yes])],
|
|
[AS_VAR_SET([spine_cv], [no])])
|
|
CFLAGS=$spine_save_CFLAGS
|
|
LDFLAGS=$spine_save_LDFLAGS
|
|
LIBS=$spine_save_LIBS])
|
|
AS_VAR_IF([spine_cv], [yes], [spine_hardening_ldflags="$spine_hardening_ldflags $1"])
|
|
AS_VAR_POPDEF([spine_cv])])
|
|
|
|
spine_hardening_cppflags=
|
|
spine_hardening_cflags=
|
|
spine_hardening_ldflags=
|
|
|
|
if test "x$enable_hardening" != xno; then
|
|
SPINE_HARDEN_CFLAG([-fstack-protector-strong])
|
|
SPINE_HARDEN_CFLAG([-fstack-clash-protection])
|
|
SPINE_HARDEN_CFLAG([-fcf-protection])
|
|
SPINE_HARDEN_CFLAG([-Wformat -Wformat-security])
|
|
|
|
dnl -static and -pie produce different, conflicting link modes. A caller
|
|
dnl that opts out of PIE keeps a non-PIE build: -fPIE in front of
|
|
dnl -fno-pie would compile non-PIE objects that the -pie link then rejects.
|
|
spine_pie_optout=no
|
|
case " $CFLAGS $LDFLAGS " in
|
|
*" -fno-pie "*|*" -fno-PIE "*|*" -no-pie "*|*" -nopie "*) spine_pie_optout=yes ;;
|
|
esac
|
|
if test "x$with_static" != xyes && test "x$spine_pie_optout" != xyes; then
|
|
SPINE_HARDEN_CFLAG([-fPIE])
|
|
case " $spine_hardening_cflags " in
|
|
*" -fPIE "*)
|
|
SPINE_HARDEN_LDFLAG([-pie])
|
|
case " $spine_hardening_ldflags " in
|
|
*" -pie "*) ;;
|
|
*) spine_hardening_cflags=`echo "$spine_hardening_cflags" | sed 's/ -fPIE//'` ;;
|
|
esac
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
SPINE_HARDEN_LDFLAG([-Wl,-z,relro,-z,now])
|
|
SPINE_HARDEN_LDFLAG([-Wl,-z,noexecstack])
|
|
|
|
dnl Leave _FORTIFY_SOURCE alone when the compiler, a distro spec file or
|
|
dnl the caller already set it, so a level 3 default is never lowered and
|
|
dnl the macro is never redefined. glibc ignores it, with a warning, below
|
|
dnl -O1, and it hides overflows from the ASan interceptors.
|
|
AC_CACHE_CHECK([whether _FORTIFY_SOURCE is already defined],
|
|
[spine_cv_fortify_preset],
|
|
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|
#include <stdio.h>
|
|
#ifndef _FORTIFY_SOURCE
|
|
#error not defined
|
|
#endif
|
|
]])],
|
|
[spine_cv_fortify_preset=yes],
|
|
[spine_cv_fortify_preset=no])])
|
|
|
|
AC_CACHE_CHECK([whether optimization is enabled],
|
|
[spine_cv_optimizing],
|
|
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|
#ifndef __OPTIMIZE__
|
|
#error not optimizing
|
|
#endif
|
|
]])],
|
|
[spine_cv_optimizing=yes],
|
|
[spine_cv_optimizing=no])])
|
|
|
|
if test "x$spine_cv_fortify_preset" = xno &&
|
|
test "x$spine_cv_optimizing" = xyes &&
|
|
test "x$enable_sanitizers" != xyes; then
|
|
dnl Level 3 needs __builtin_dynamic_object_size (GCC 12, Clang 9).
|
|
AC_CACHE_CHECK([for the highest supported _FORTIFY_SOURCE level],
|
|
[spine_cv_fortify_level],
|
|
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|
#if !defined(__has_builtin)
|
|
#error no __has_builtin
|
|
#elif !__has_builtin(__builtin_dynamic_object_size)
|
|
#error no __builtin_dynamic_object_size
|
|
#endif
|
|
]])],
|
|
[spine_cv_fortify_level=3],
|
|
[spine_cv_fortify_level=2])])
|
|
spine_hardening_cppflags="-D_FORTIFY_SOURCE=$spine_cv_fortify_level"
|
|
fi
|
|
|
|
CPPFLAGS="$spine_hardening_cppflags $CPPFLAGS"
|
|
CFLAGS="$spine_hardening_cflags $CFLAGS"
|
|
LDFLAGS="$spine_hardening_ldflags $LDFLAGS"
|
|
fi
|
|
|
|
AC_MSG_NOTICE([hardening CPPFLAGS:${spine_hardening_cppflags:+ $spine_hardening_cppflags}])
|
|
AC_MSG_NOTICE([hardening CFLAGS:$spine_hardening_cflags])
|
|
AC_MSG_NOTICE([hardening LDFLAGS:$spine_hardening_ldflags])
|
|
|
|
# cmocka is only used by the unit tests under "make check". Absence is not
|
|
# fatal; the tests are dropped from check_PROGRAMS instead.
|
|
have_cmocka=no
|
|
AC_CHECK_LIB([cmocka], [_cmocka_run_group_tests], [have_cmocka=yes])
|
|
if test "x$have_cmocka" = xyes; then
|
|
AC_CHECK_HEADER([cmocka.h], [], [have_cmocka=no], [[
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <setjmp.h>
|
|
]])
|
|
fi
|
|
|
|
CMOCKA_LIBS=
|
|
if test "x$have_cmocka" = xyes; then
|
|
CMOCKA_LIBS=-lcmocka
|
|
fi
|
|
AC_SUBST(CMOCKA_LIBS)
|
|
AM_CONDITIONAL([HAVE_CMOCKA], [test "x$have_cmocka" = xyes])
|
|
|
|
AC_CONFIG_FILES([Makefile])
|
|
AC_OUTPUT
|