#! /bin/sh # # Copyright (c) 2014, 2015, 2016 Ingo Schwarze # Copyright (c) 2017, 2018 Kristaps Dzonsons # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OCONFIGURE_VERSION="0.3.13" # # This script outputs two files: config.h and Makefile.configure. # It tries to read from configure.local, which contains predefined # values we won't autoconfigure. # # If you want to use configure with your project, have your GNUmakefile # or BSDmakefile---whichever---try to import/include Makefile.configure # at the beginning of the file. # # Like so (note no quotes, no period, etc.): # # include Makefile.configure # # If it exists, configure was run; otherwise, it wasn't. # # You'll probably want to change parts of this file. I've noted the # parts that you'll probably change in the section documentation. # # See https://github.com/kristapsdz/oconfigure for more. set -e #---------------------------------------------------------------------- # Prepare for running: move aside previous configure runs. # Output file descriptor usage: # 1 (stdout): config.h or Makefile.configure # 2 (stderr): original stderr, usually to the console # 3: config.log # You DO NOT want to change this. #---------------------------------------------------------------------- [ -w config.log ] && mv config.log config.log.old [ -w config.h ] && mv config.h config.h.old exec 3> config.log echo "config.log: writing..." # GNU submake prints different output if invoked recursively, which # messes up CC and CFLAGS detection. Pass --no-print-directory if # we have a MAKELEVEL (GNU and FreeBSD make) and the argument is # allowed. MAKE_FLAGS="" if [ -n "${MAKELEVEL}" ]; then if [ "${MAKELEVEL}" -gt 0 ] ; then MAKE_FLAGS="--no-print-directory" echo "all:" | make ${MAKE_FLAGS} -sf - 2>/dev/null || MAKE_FLAGS="" fi fi if [ -n "$MAKE_FLAGS" ]; then echo "GNU submake detected: using --no-print-directory" 1>&2 echo "GNU submake detected: using --no-print-directory" 1>&3 fi #---------------------------------------------------------------------- # Initialise all variables here such that nothing can leak in from the # environment except for AR, CC and CFLAGS, which we might have passed # in. #---------------------------------------------------------------------- AR=`printf "all:\\n\\t@echo \\\$(AR)\\n" | make ${MAKE_FLAGS} -sf -` CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make ${MAKE_FLAGS} -sf -` CFLAGS=`printf "all:\\n\\t@echo \\\$(CFLAGS)\\n" | make ${MAKE_FLAGS} -sf -` CFLAGS="${CFLAGS} -g -W -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes" CFLAGS="${CFLAGS} -Wwrite-strings -Wno-unused-parameter" LDLIBS= LDADD= LDADD_B64_NTOP= LDADD_CRYPT= LDADD_MD5= LDADD_SHA2= LDADD_LIB_SOCKET= LDADD_SCAN_SCALED= LDADD_STATIC= CPPFLAGS= LDFLAGS= LINKER_SONAME= DESTDIR= PREFIX="/usr/local" BINDIR= SBINDIR= INCLUDEDIR= LIBDIR= MANDIR= SHAREDIR= INSTALL="install" INSTALL_PROGRAM= INSTALL_LIB= INSTALL_MAN= INSTALL_DATA= # SunOS sets "cc", but this doesn't exist. # It does have gcc, so try that instead. # Prefer clang, though. command -v ${CC} 2>/dev/null 1>&2 || { echo "${CC} not found: trying clang" 1>&2 echo "${CC} not found: trying clang" 1>&3 CC=clang command -v ${CC} 2>/dev/null 1>&2 || { echo "${CC} not found: trying gcc" 1>&2 echo "${CC} not found: trying gcc" 1>&3 CC=gcc command -v ${CC} 2>/dev/null 1>&2 || { echo "gcc not found: giving up" 1>&2 echo "gcc not found: giving up" 1>&3 exit 1 } } } #---------------------------------------------------------------------- # Allow certain variables to be overriden on the command line. #---------------------------------------------------------------------- for keyvals in "$@" do key=`echo $keyvals | cut -s -d '=' -f 1` if [ -z "$key" ] then echo "$0: invalid key-value: $keyvals" 1>&2 exit 1 fi val=`echo $keyvals | cut -d '=' -f 2-` case "$key" in LDADD) LDADD="$val" ;; LDLIBS) LDLIBS="$val" ;; LDFLAGS) LDFLAGS="$val" ;; LINKER_SONAME) LINKER_SONAME="$val" ;; CPPFLAGS) CPPFLAGS="$val" ;; DESTDIR) DESTDIR="$val" ;; PREFIX) PREFIX="$val" ;; MANDIR) MANDIR="$val" ;; LIBDIR) LIBDIR="$val" ;; BINDIR) BINDIR="$val" ;; SHAREDIR) SHAREDIR="$val" ;; SBINDIR) SBINDIR="$val" ;; INCLUDEDIR) INCLUDEDIR="$val" ;; *) echo "$0: invalid key: $key" 1>&2 exit 1 esac done #---------------------------------------------------------------------- # If the user doesn't specify whether we want "-soname" or # "-install_name" for the linker option to generate shared libraries, # try to figure it out here. If we can't figure it out, just set it to # -soname and let the user figure it out. if [ -z "$LINKER_SONAME" ] then test_soname="`mktemp`" || { echo "mktemp: failed" 1>&2 echo "mktemp: failed" 1>&3 exit 1 } echo "int foo(void) { return 1; }" > "${test_soname}.c" ${CC} -fPIC -o ${test_soname}.o -c ${test_soname}.c || { echo "${CC} -fPIC -o ${test_soname}.o -c ${test_soname}.c: failed" 1>&2 echo "${CC} -fPIC -o ${test_soname}.o -c ${test_soname}.c: failed" 1>&3 } LINKER_SONAME="-soname" echo "LINKER_SONAME: testing -soname" 1>&3 ${CC} -shared -o ${test_soname}.so.0 ${test_soname}.o -Wl,${LINKER_SONAME},${test_soname}.so.0 || { LINKER_SONAME="-install_name" echo "LINKER_SONAME: testing -install_name" 1>&3 ${CC} -shared -o ${test_soname}.so.0 ${test_soname}.o -Wl,-install_name,${test_soname}.so.0 || { echo "LINKER_SONAME: cannot determine: default to -soname" 1>&2 echo "LINKER_SONAME: cannot determine: default to -soname" 1>&3 LINKER_SONAME="-soname" } } echo "LINKER_SONAME: $LINKER_SONAME" 1>&3 rm -f "$test_soname" "${test_soname}.*" fi #---------------------------------------------------------------------- # These are the values that will be pushed into config.h after we test # for whether they're supported or not. # Each of these must have a runtest(), below. # Please sort by alpha, for clarity. # You WANT to change this. #---------------------------------------------------------------------- HAVE_ARC4RANDOM= HAVE_B64_NTOP= HAVE_CAPSICUM= HAVE_CRYPT= HAVE_CRYPT_NEWHASH= HAVE_ENDIAN_H= HAVE_ERR= HAVE_EXPLICIT_BZERO= HAVE_FTS= HAVE_GETEXECNAME= HAVE_GETPROGNAME= HAVE_INFTIM= HAVE_LANDLOCK= HAVE_MD5= HAVE_MEMMEM= HAVE_MEMRCHR= HAVE_MEMSET_S= HAVE_MKFIFOAT= HAVE_MKNODAT= HAVE_OSBYTEORDER_H= HAVE_PATH_MAX= HAVE_PLEDGE= HAVE_PROGRAM_INVOCATION_SHORT_NAME= HAVE_READPASSPHRASE= HAVE_REALLOCARRAY= HAVE_RECALLOCARRAY= HAVE_SANDBOX_INIT= HAVE_SCAN_SCALED= HAVE_SECCOMP_FILTER= HAVE_SETRESGID= HAVE_SETRESUID= HAVE_SOCK_NONBLOCK= HAVE_SHA2= HAVE_SHA2_H= HAVE_STRLCAT= HAVE_STRLCPY= HAVE_STRNDUP= HAVE_STRNLEN= HAVE_STRTONUM= HAVE_SYS_BYTEORDER_H= HAVE_SYS_ENDIAN_H= HAVE_SYS_MKDEV_H= HAVE_SYS_QUEUE= HAVE_SYS_SYSMACROS= HAVE_SYS_TREE= HAVE_SYSTRACE=0 HAVE_TERMIOS= HAVE_UNVEIL= HAVE_WAIT_ANY= HAVE___PROGNAME= #---------------------------------------------------------------------- # Allow configure.local to override all variables, default settings, # command-line arguments, and tested features, above. # You PROBABLY DO NOT want to change this. #---------------------------------------------------------------------- if [ -r ./configure.local ]; then echo "configure.local: reading..." 1>&2 echo "configure.local: reading..." 1>&3 cat ./configure.local 1>&3 . ./configure.local else echo "configure.local: no (fully automatic configuration)" 1>&2 echo "configure.local: no (fully automatic configuration)" 1>&3 fi echo 1>&3 #---------------------------------------------------------------------- # Infrastructure for running tests. # These consists of a series of functions that will attempt to run the # given test file and record its exit into a HAVE_xxx variable. # You DO NOT want to change this. #---------------------------------------------------------------------- COMP="${CC} ${CFLAGS} ${CPPFLAGS} -Wno-unused -Werror" # Check whether this HAVE_ setting is manually overridden. # If yes, use the override, if no, do not decide anything yet. # Arguments: lower-case test name, manual value ismanual() { [ -z "${3}" ] && return 1 echo "${1}: manual (HAVE_${2}=${3})" 1>&2 echo "${1}: manual (HAVE_${2}=${3})" 1>&3 echo 1>&3 return 0 } # Run a single autoconfiguration test. # In case of success, enable the feature. # In case of failure, do not decide anything yet. # Arguments: lower-case test name, upper-case test name, additional # CFLAGS, additional LIBS. singletest() { extralib="" cat 1>&3 << __HEREDOC__ ${1}: testing... ${COMP} -DTEST_${2} ${3} -o test-${1} tests.c ${LDFLAGS} ${4} __HEREDOC__ if ${COMP} -DTEST_${2} ${3} -o "test-${1}" tests.c ${LDFLAGS} ${4} 1>&3 2>&3; then echo "${1}: ${CC} succeeded" 1>&3 else if [ -n "${5}" ] ; then echo "${1}: ${CC} failed with $? (retrying)" 1>&3 cat 1>&3 << __HEREDOC__ ${1}: testing... ${COMP} -DTEST_${2} ${3} -o test-${1} tests.c ${LDFLAGS} ${5} __HEREDOC__ if ${COMP} -DTEST_${2} ${3} -o "test-${1}" tests.c ${LDFLAGS} ${5} 1>&3 2>&3; then echo "${1}: ${CC} succeeded" 1>&3 extralib="(with ${5})" else echo "${1}: ${CC} failed with $?" 1>&3 echo 1>&3 return 1 fi else echo "${1}: ${CC} failed with $?" 1>&3 echo 1>&3 return 1 fi fi if [ -n "${extralib}" ] then eval "LDADD_${2}=\"${5}\"" elif [ -n "${4}" ] then eval "LDADD_${2}=\"${4}\"" fi echo "${1}: yes ${extralib}" 1>&2 echo "${1}: yes ${extralib}" 1>&3 echo 1>&3 eval HAVE_${2}=1 rm "test-${1}" return 0 } # Run a complete autoconfiguration test, including the check for # a manual override and disabling the feature on failure. # Arguments: lower case name, upper case name, additional CFLAGS, # additional LDADD, alternative LDADD. runtest() { eval _manual=\${HAVE_${2}} ismanual "${1}" "${2}" "${_manual}" && return 0 singletest "${1}" "${2}" "${3}" "${4}" "${5}" && return 0 echo "${1}: no" 1>&2 eval HAVE_${2}=0 return 1 } #---------------------------------------------------------------------- # Begin running the tests themselves. # All of your tests must be defined here. # Please sort as the HAVE_xxxx values were defined. # You WANT to change this. # It consists of the following columns: # runtest # (1) test file # (2) macro to set # (3) argument to cc *before* -o # (4) argument to cc *after* # (5) alternative argument to cc *after* #---------------------------------------------------------------------- runtest arc4random ARC4RANDOM || true runtest b64_ntop B64_NTOP "" "" "-lresolv" || true runtest capsicum CAPSICUM || true runtest crypt CRYPT "" "" "-lcrypt" || true runtest crypt_newhash CRYPT_NEWHASH || true runtest endian_h ENDIAN_H || true runtest err ERR || true runtest explicit_bzero EXPLICIT_BZERO || true runtest fts FTS || true runtest getexecname GETEXECNAME || true runtest getprogname GETPROGNAME || true runtest INFTIM INFTIM || true runtest landlock LANDLOCK || true runtest lib_socket LIB_SOCKET "" "" "-lsocket -lnsl" || true runtest md5 MD5 "" "" "-lmd" || true runtest memmem MEMMEM || true runtest memrchr MEMRCHR || true runtest memset_s MEMSET_S || true runtest mkfifoat MKFIFOAT || true runtest mknodat MKNODAT || true runtest osbyteorder_h OSBYTEORDER_H || true runtest PATH_MAX PATH_MAX || true runtest pledge PLEDGE || true runtest program_invocation_short_name PROGRAM_INVOCATION_SHORT_NAME || true runtest readpassphrase READPASSPHRASE || true runtest reallocarray REALLOCARRAY || true runtest recallocarray RECALLOCARRAY || true runtest sandbox_init SANDBOX_INIT "-Wno-deprecated" || true runtest scan_scaled SCAN_SCALED "" "" "-lutil" || true runtest seccomp-filter SECCOMP_FILTER || true runtest setresgid SETRESGID || true runtest setresuid SETRESUID || true runtest sha2 SHA2 "" "" "-lmd" || true runtest SOCK_NONBLOCK SOCK_NONBLOCK || true runtest static STATIC "" "-static" || true runtest strlcat STRLCAT || true runtest strlcpy STRLCPY || true runtest strndup STRNDUP || true runtest strnlen STRNLEN || true runtest strtonum STRTONUM || true runtest sys_byteorder_h SYS_BYTEORDER_H || true runtest sys_endian_h SYS_ENDIAN_H || true runtest sys_mkdev_h SYS_MKDEV_H || true runtest sys_sysmacros_h SYS_SYSMACROS_H || true runtest sys_queue SYS_QUEUE || true runtest sys_tree SYS_TREE || true runtest termios TERMIOS || true runtest unveil UNVEIL || true runtest WAIT_ANY WAIT_ANY || true runtest __progname __PROGNAME || true #---------------------------------------------------------------------- # Output writing: generate the config.h file. # This file contains all of the HAVE_xxxx variables necessary for # compiling your source. # You must include "config.h" BEFORE any other variables. # You WANT to change this. #---------------------------------------------------------------------- exec > config.h # Start with prologue. cat << __HEREDOC__ #ifndef OCONFIGURE_CONFIG_H #define OCONFIGURE_CONFIG_H #ifdef __cplusplus # error "Do not use C++: this is a C application." #endif #if !defined(__GNUC__) || (__GNUC__ < 4) # define __attribute__(x) #endif #if defined(__linux__) || defined(__MINT__) || defined(__wasi__) # define _GNU_SOURCE /* memmem, memrchr, setresuid... */ # define _DEFAULT_SOURCE /* le32toh, crypt, ... */ #endif #if defined(__NetBSD__) # define _OPENBSD_SOURCE /* reallocarray, etc. */ #endif #if defined(__sun) # ifndef _XOPEN_SOURCE /* SunOS already defines */ # define _XOPEN_SOURCE /* XPGx */ # endif # define _XOPEN_SOURCE_EXTENDED 1 /* XPG4v2 */ # ifndef __EXTENSIONS__ /* SunOS already defines */ # define __EXTENSIONS__ /* reallocarray, etc. */ # endif #endif #if !defined(__BEGIN_DECLS) # define __BEGIN_DECLS #endif #if !defined(__END_DECLS) # define __END_DECLS #endif __HEREDOC__ # This is just for size_t, mode_t, and dev_t. # Most of these functions, in the real world, pull in or # someting that pulls in support for size_t. # Our function declarations are standalone, so specify them here. if [ ${HAVE_FTS} -eq 0 -o \ ${HAVE_MD5} -eq 0 -o \ ${HAVE_MEMMEM} -eq 0 -o \ ${HAVE_MEMRCHR} -eq 0 -o \ ${HAVE_MKFIFOAT} -eq 0 -o \ ${HAVE_MKNODAT} -eq 0 -o \ ${HAVE_READPASSPHRASE} -eq 0 -o \ ${HAVE_REALLOCARRAY} -eq 0 -o \ ${HAVE_RECALLOCARRAY} -eq 0 -o \ ${HAVE_SETRESGID} -eq 0 -o \ ${HAVE_SETRESUID} -eq 0 -o \ ${HAVE_SHA2} -eq 0 -o \ ${HAVE_STRLCAT} -eq 0 -o \ ${HAVE_STRLCPY} -eq 0 -o \ ${HAVE_STRNDUP} -eq 0 -o \ ${HAVE_STRNLEN} -eq 0 ] then echo "#include /* size_t, mode_t, dev_t */ " echo fi if [ ${HAVE_MD5} -eq 0 -o \ ${HAVE_SHA2} -eq 0 ] then echo "#include /* C99 [u]int[nn]_t types */" echo fi if [ ${HAVE_ERR} -eq 0 ] then echo "#include /* err(3) */" echo fi # Now we handle our HAVE_xxxx values. # Most will just be defined as 0 or 1. if [ ${HAVE_PATH_MAX} -eq 0 ] then echo "#define PATH_MAX 4096" echo fi if [ ${HAVE_WAIT_ANY} -eq 0 ] then echo "#define WAIT_ANY (-1) /* sys/wait.h */" echo "#define WAIT_MYPGRP 0" echo fi if [ ${HAVE_INFTIM} -eq 0 ] then echo "#define INFTIM (-1) /* poll.h */" echo fi cat << __HEREDOC__ /* * Results of configuration feature-testing. */ #define HAVE_ARC4RANDOM ${HAVE_ARC4RANDOM} #define HAVE_B64_NTOP ${HAVE_B64_NTOP} #define HAVE_CAPSICUM ${HAVE_CAPSICUM} #define HAVE_CRYPT ${HAVE_CRYPT} #define HAVE_CRYPT_NEWHASH ${HAVE_CRYPT_NEWHASH} #define HAVE_ENDIAN_H ${HAVE_ENDIAN_H} #define HAVE_ERR ${HAVE_ERR} #define HAVE_EXPLICIT_BZERO ${HAVE_EXPLICIT_BZERO} #define HAVE_FTS ${HAVE_FTS} #define HAVE_GETEXECNAME ${HAVE_GETEXECNAME} #define HAVE_GETPROGNAME ${HAVE_GETPROGNAME} #define HAVE_INFTIM ${HAVE_INFTIM} #define HAVE_LANDLOCK ${HAVE_LANDLOCK} #define HAVE_MD5 ${HAVE_MD5} #define HAVE_MEMMEM ${HAVE_MEMMEM} #define HAVE_MEMRCHR ${HAVE_MEMRCHR} #define HAVE_MEMSET_S ${HAVE_MEMSET_S} #define HAVE_MKFIFOAT ${HAVE_MKFIFOAT} #define HAVE_MKNODAT ${HAVE_MKNODAT} #define HAVE_OSBYTEORDER_H ${HAVE_OSBYTEORDER_H} #define HAVE_PATH_MAX ${HAVE_PATH_MAX} #define HAVE_PLEDGE ${HAVE_PLEDGE} #define HAVE_PROGRAM_INVOCATION_SHORT_NAME ${HAVE_PROGRAM_INVOCATION_SHORT_NAME} #define HAVE_READPASSPHRASE ${HAVE_READPASSPHRASE} #define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} #define HAVE_RECALLOCARRAY ${HAVE_RECALLOCARRAY} #define HAVE_SANDBOX_INIT ${HAVE_SANDBOX_INIT} #define HAVE_SCAN_SCALED ${HAVE_SCAN_SCALED} #define HAVE_SECCOMP_HEADER ${HAVE_SECCOMP_FILTER} #define HAVE_SETRESGID ${HAVE_SETRESGID} #define HAVE_SETRESUID ${HAVE_SETRESUID} #define HAVE_SHA2 ${HAVE_SHA2} #define HAVE_SHA2_H ${HAVE_SHA2} #define HAVE_SOCK_NONBLOCK ${HAVE_SOCK_NONBLOCK} #define HAVE_STRLCAT ${HAVE_STRLCAT} #define HAVE_STRLCPY ${HAVE_STRLCPY} #define HAVE_STRNDUP ${HAVE_STRNDUP} #define HAVE_STRNLEN ${HAVE_STRNLEN} #define HAVE_STRTONUM ${HAVE_STRTONUM} #define HAVE_SYS_BYTEORDER_H ${HAVE_SYS_BYTEORDER_H} #define HAVE_SYS_ENDIAN_H ${HAVE_SYS_ENDIAN_H} #define HAVE_SYS_MKDEV_H ${HAVE_SYS_MKDEV_H} #define HAVE_SYS_QUEUE ${HAVE_SYS_QUEUE} #define HAVE_SYS_SYSMACROS_H ${HAVE_SYS_SYSMACROS_H} #define HAVE_SYS_TREE ${HAVE_SYS_TREE} #define HAVE_SYSTRACE ${HAVE_SYSTRACE} #define HAVE_UNVEIL ${HAVE_UNVEIL} #define HAVE_TERMIOS ${HAVE_TERMIOS} #define HAVE_WAIT_ANY ${HAVE_WAIT_ANY} #define HAVE___PROGNAME ${HAVE___PROGNAME} __HEREDOC__ # Compat for libkern/OSByteOrder.h in place of endian.h. [ ${HAVE_OSBYTEORDER_H} -eq 1 -a \ ${HAVE_ENDIAN_H} -eq 0 -a \ ${HAVE_SYS_BYTEORDER_H} -eq 0 -a \ ${HAVE_SYS_ENDIAN_H} -eq 0 ] \ && cat << __HEREDOC__ /* * endian.h compatibility with libkern/OSByteOrder.h. */ #define htobe16(x) OSSwapHostToBigInt16(x) #define htole16(x) OSSwapHostToLittleInt16(x) #define be16toh(x) OSSwapBigToHostInt16(x) #define le16toh(x) OSSwapLittleToHostInt16(x) #define htobe32(x) OSSwapHostToBigInt32(x) #define htole32(x) OSSwapHostToLittleInt32(x) #define be32toh(x) OSSwapBigToHostInt32(x) #define le32toh(x) OSSwapLittleToHostInt32(x) #define htobe64(x) OSSwapHostToBigInt64(x) #define htole64(x) OSSwapHostToLittleInt64(x) #define be64toh(x) OSSwapBigToHostInt64(x) #define le64toh(x) OSSwapLittleToHostInt64(x) __HEREDOC__ [ ${HAVE_SYS_BYTEORDER_H} -eq 1 -a \ ${HAVE_ENDIAN_H} -eq 0 -a \ ${HAVE_OSBYTEORDER_H} -eq 0 -a \ ${HAVE_SYS_ENDIAN_H} -eq 0 ] \ && cat << __HEREDOC__ /* * endian.h compatibility with sys/byteorder.h. */ #define htobe16(x) BE_16(x) #define htole16(x) LE_16(x) #define be16toh(x) BE_16(x) #define le16toh(x) LE_16(x) #define htobe32(x) BE_32(x) #define htole32(x) LE_32(x) #define be32toh(x) BE_32(x) #define le32toh(x) LE_32(x) #define htobe64(x) BE_64(x) #define htole64(x) LE_64(x) #define be64toh(x) BE_64(x) #define le64toh(x) LE_64(x) __HEREDOC__ # Make minor()/major()/makedev() easier to use. cat << __HEREDOC__ /* * Handle the various major()/minor() header files. * Use sys/mkdev.h before sys/sysmacros.h because SunOS * has both, where only the former works properly. */ #if HAVE_SYS_MKDEV_H # define COMPAT_MAJOR_MINOR_H #elif HAVE_SYS_SYSMACROS_H # define COMPAT_MAJOR_MINOR_H #else # define COMPAT_MAJOR_MINOR_H #endif __HEREDOC__ # Make endian.h easier by providing a COMPAT_ENDIAN_H. cat << __HEREDOC__ /* * Make it easier to include endian.h forms. */ #if HAVE_ENDIAN_H # define COMPAT_ENDIAN_H #elif HAVE_SYS_ENDIAN_H # define COMPAT_ENDIAN_H #elif HAVE_OSBYTEORDER_H # define COMPAT_ENDIAN_H #elif HAVE_SYS_BYTEORDER_H # define COMPAT_ENDIAN_H #else # warning No suitable endian.h could be found. # warning Please e-mail the maintainers with your OS. # define COMPAT_ENDIAN_H #endif __HEREDOC__ # Now we do our function declarations for missing functions. [ ${HAVE_ERR} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility functions for err(3). */ extern void err(int, const char *, ...) __attribute__((noreturn)); extern void errc(int, int, const char *, ...) __attribute__((noreturn)); extern void errx(int, const char *, ...) __attribute__((noreturn)); extern void verr(int, const char *, va_list) __attribute__((noreturn)); extern void verrc(int, int, const char *, va_list) __attribute__((noreturn)); extern void verrx(int, const char *, va_list) __attribute__((noreturn)); extern void warn(const char *, ...); extern void warnx(const char *, ...); extern void warnc(int, const char *, ...); extern void vwarn(const char *, va_list); extern void vwarnc(int, const char *, va_list); extern void vwarnx(const char *, va_list); __HEREDOC__ [ ${HAVE_MD5} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for md4(3). */ #define MD5_BLOCK_LENGTH 64 #define MD5_DIGEST_LENGTH 16 #define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1) typedef struct MD5Context { uint32_t state[4]; uint64_t count; uint8_t buffer[MD5_BLOCK_LENGTH]; } MD5_CTX; extern void MD5Init(MD5_CTX *); extern void MD5Update(MD5_CTX *, const uint8_t *, size_t); extern void MD5Pad(MD5_CTX *); extern void MD5Transform(uint32_t [4], const uint8_t [MD5_BLOCK_LENGTH]); extern char *MD5End(MD5_CTX *, char *); extern void MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *); __HEREDOC__ [ ${HAVE_SHA2} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for sha2(3). */ /*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 #define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) #define SHA384_BLOCK_LENGTH 128 #define SHA384_DIGEST_LENGTH 48 #define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) #define SHA512_BLOCK_LENGTH 128 #define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) #define SHA512_256_BLOCK_LENGTH 128 #define SHA512_256_DIGEST_LENGTH 32 #define SHA512_256_DIGEST_STRING_LENGTH (SHA512_256_DIGEST_LENGTH * 2 + 1) /*** SHA-224/256/384/512 Context Structure *******************************/ typedef struct _SHA2_CTX { union { uint32_t st32[8]; uint64_t st64[8]; } state; uint64_t bitcount[2]; uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA2_CTX; void SHA256Init(SHA2_CTX *); void SHA256Transform(uint32_t state[8], const uint8_t [SHA256_BLOCK_LENGTH]); void SHA256Update(SHA2_CTX *, const uint8_t *, size_t); void SHA256Pad(SHA2_CTX *); void SHA256Final(uint8_t [SHA256_DIGEST_LENGTH], SHA2_CTX *); char *SHA256End(SHA2_CTX *, char *); char *SHA256File(const char *, char *); char *SHA256FileChunk(const char *, char *, off_t, off_t); char *SHA256Data(const uint8_t *, size_t, char *); void SHA384Init(SHA2_CTX *); void SHA384Transform(uint64_t state[8], const uint8_t [SHA384_BLOCK_LENGTH]); void SHA384Update(SHA2_CTX *, const uint8_t *, size_t); void SHA384Pad(SHA2_CTX *); void SHA384Final(uint8_t [SHA384_DIGEST_LENGTH], SHA2_CTX *); char *SHA384End(SHA2_CTX *, char *); char *SHA384File(const char *, char *); char *SHA384FileChunk(const char *, char *, off_t, off_t); char *SHA384Data(const uint8_t *, size_t, char *); void SHA512Init(SHA2_CTX *); void SHA512Transform(uint64_t state[8], const uint8_t [SHA512_BLOCK_LENGTH]); void SHA512Update(SHA2_CTX *, const uint8_t *, size_t); void SHA512Pad(SHA2_CTX *); void SHA512Final(uint8_t [SHA512_DIGEST_LENGTH], SHA2_CTX *); char *SHA512End(SHA2_CTX *, char *); char *SHA512File(const char *, char *); char *SHA512FileChunk(const char *, char *, off_t, off_t); char *SHA512Data(const uint8_t *, size_t, char *); __HEREDOC__ if [ ${HAVE_SECCOMP_FILTER} -eq 1 ]; then seccomp_audit_arch= arch=$(uname -m 2>/dev/null || echo unknown) case "$arch" in x86_64) seccomp_audit_arch=AUDIT_ARCH_X86_64 ;; i*86) seccomp_audit_arch=AUDIT_ARCH_I386 ;; arm*) seccomp_audit_arch=AUDIT_ARCH_ARM ;; aarch64*) seccomp_audit_arch=AUDIT_ARCH_AARCH64 ;; s390x) seccomp_audit_arch=AUDIT_ARCH_S390X ;; s390) seccomp_audit_arch=AUDIT_ARCH_S390 ;; ppc) seccomp_audit_arch=AUDIT_ARCH_PPC ;; ppc64) seccomp_audit_arch=AUDIT_ARCH_PPC64 ;; ppc64le) seccomp_audit_arch=AUDIT_ARCH_PPC64LE ;; mips) seccomp_audit_arch=AUDIT_ARCH_MIPS ;; mipsel) seccomp_audit_arch=AUDIT_ARCH_MIPSEL ;; riscv64) seccomp_audit_arch=AUDIT_ARCH_RISCV64 ;; esac if [ -n "$seccomp_audit_arch" ] then echo "seccomp-arch: $seccomp_audit_arch" 1>&2 cat << __HEREDOC__ /* * Seccomp is both available and has a recognised architecture. */ #define HAVE_SECCOMP_FILTER 1 #define SECCOMP_AUDIT_ARCH $seccomp_audit_arch __HEREDOC__ else echo "seccomp-arch: disabling (unknown: `uname -m`)" 1>&2 cat << __HEREDOC__ /** * Seccomp is available, but not with a recognised architecture. * Please submit your architecture (via uname -m) to the oconfigure * maintainers. */ #define HAVE_SECCOMP_FILTER 0 __HEREDOC__ fi else cat << __HEREDOC__ #define HAVE_SECCOMP_FILTER 0 __HEREDOC__ fi [ ${HAVE_B64_NTOP} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for b64_ntop(3). */ extern int b64_ntop(unsigned char const *, size_t, char *, size_t); extern int b64_pton(char const *, unsigned char *, size_t); __HEREDOC__ [ ${HAVE_SCAN_SCALED} -eq 0 ] && \ cat << __HEREDOC__ #define FMT_SCALED_STRSIZE 7 /* minus sign, 4 digits, suffix, null byte */ int fmt_scaled(long long, char *); int scan_scaled(char *, long long *); __HEREDOC__ [ ${HAVE_EXPLICIT_BZERO} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for explicit_bzero(3). */ extern void explicit_bzero(void *, size_t); __HEREDOC__ [ ${HAVE_MEMMEM} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for memmem(3). */ void *memmem(const void *, size_t, const void *, size_t); __HEREDOC__ [ ${HAVE_MEMRCHR} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for memrchr(3). */ void *memrchr(const void *b, int, size_t); __HEREDOC__ [ ${HAVE_GETPROGNAME} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for getprogname(3). */ extern const char *getprogname(void); __HEREDOC__ [ ${HAVE_READPASSPHRASE} -eq 0 ] && \ cat << __HEREDOC__ /* * Macros and function required for readpassphrase(3). */ #define RPP_ECHO_OFF 0x00 #define RPP_ECHO_ON 0x01 #define RPP_REQUIRE_TTY 0x02 #define RPP_FORCELOWER 0x04 #define RPP_FORCEUPPER 0x08 #define RPP_SEVENBIT 0x10 #define RPP_STDIN 0x20 char *readpassphrase(const char *, char *, size_t, int); __HEREDOC__ [ ${HAVE_REALLOCARRAY} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for reallocarray(3). */ extern void *reallocarray(void *, size_t, size_t); __HEREDOC__ [ ${HAVE_RECALLOCARRAY} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for recallocarray(3). */ extern void *recallocarray(void *, size_t, size_t, size_t); __HEREDOC__ [ ${HAVE_STRLCAT} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for strlcat(3). */ extern size_t strlcat(char *, const char *, size_t); __HEREDOC__ [ ${HAVE_STRLCPY} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for strlcpy(3). */ extern size_t strlcpy(char *, const char *, size_t); __HEREDOC__ [ ${HAVE_STRNDUP} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for strndup(3). */ extern char *strndup(const char *, size_t); __HEREDOC__ [ ${HAVE_STRNLEN} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for strnlen(3). */ extern size_t strnlen(const char *, size_t); __HEREDOC__ [ ${HAVE_STRTONUM} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for strotnum(3). */ extern long long strtonum(const char *, long long, long long, const char **); __HEREDOC__ [ ${HAVE_MKFIFOAT} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for mkfifoat(2). */ int mkfifoat(int, const char *, mode_t); __HEREDOC__ [ ${HAVE_MKNODAT} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for mknodat(2). */ int mknodat(int, const char *, mode_t, dev_t); __HEREDOC__ [ ${HAVE_SETRESGID} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for setresgid(2). */ int setresgid(gid_t rgid, gid_t egid, gid_t sgid); __HEREDOC__ [ ${HAVE_SETRESUID} -eq 0 ] && \ cat << __HEREDOC__ /* * Compatibility for setresuid(2). */ int setresuid(uid_t ruid, uid_t euid, uid_t suid); __HEREDOC__ if [ ${HAVE_SYS_QUEUE} -eq 0 ]; then cat << __HEREDOC__ /* * A compatible version of OpenBSD . */ /* * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)queue.h 8.5 (Berkeley) 8/20/94 */ /* OPENBSD ORIGINAL: sys/sys/queue.h */ /* * Require for OS/X and other platforms that have old/broken/incomplete * . */ #undef LIST_EMPTY #undef LIST_END #undef LIST_ENTRY #undef LIST_FIRST #undef LIST_FOREACH #undef LIST_FOREACH_SAFE #undef LIST_HEAD #undef LIST_HEAD_INITIALIZER #undef LIST_INIT #undef LIST_INSERT_AFTER #undef LIST_INSERT_BEFORE #undef LIST_INSERT_HEAD #undef LIST_NEXT #undef LIST_REMOVE #undef LIST_REPLACE #undef SIMPLEQ_CONCAT #undef SIMPLEQ_EMPTY #undef SIMPLEQ_END #undef SIMPLEQ_ENTRY #undef SIMPLEQ_FIRST #undef SIMPLEQ_FOREACH #undef SIMPLEQ_FOREACH_SAFE #undef SIMPLEQ_HEAD #undef SIMPLEQ_HEAD_INITIALIZER #undef SIMPLEQ_INIT #undef SIMPLEQ_INSERT_AFTER #undef SIMPLEQ_INSERT_HEAD #undef SIMPLEQ_INSERT_TAIL #undef SIMPLEQ_NEXT #undef SIMPLEQ_REMOVE_AFTER #undef SIMPLEQ_REMOVE_HEAD #undef SLIST_EMPTY #undef SLIST_END #undef SLIST_ENTRY #undef SLIST_FIRST #undef SLIST_FOREACH #undef SLIST_FOREACH_SAFE #undef SLIST_HEAD #undef SLIST_HEAD_INITIALIZER #undef SLIST_INIT #undef SLIST_INSERT_AFTER #undef SLIST_INSERT_HEAD #undef SLIST_NEXT #undef SLIST_REMOVE #undef SLIST_REMOVE_AFTER #undef SLIST_REMOVE_HEAD #undef TAILQ_CONCAT #undef TAILQ_EMPTY #undef TAILQ_END #undef TAILQ_ENTRY #undef TAILQ_FIRST #undef TAILQ_FOREACH #undef TAILQ_FOREACH_REVERSE #undef TAILQ_FOREACH_REVERSE_SAFE #undef TAILQ_FOREACH_SAFE #undef TAILQ_HEAD #undef TAILQ_HEAD_INITIALIZER #undef TAILQ_INIT #undef TAILQ_INSERT_AFTER #undef TAILQ_INSERT_BEFORE #undef TAILQ_INSERT_HEAD #undef TAILQ_INSERT_TAIL #undef TAILQ_LAST #undef TAILQ_NEXT #undef TAILQ_PREV #undef TAILQ_REMOVE #undef TAILQ_REPLACE #undef XSIMPLEQ_EMPTY #undef XSIMPLEQ_END #undef XSIMPLEQ_ENTRY #undef XSIMPLEQ_FIRST #undef XSIMPLEQ_FOREACH #undef XSIMPLEQ_FOREACH_SAFE #undef XSIMPLEQ_HEAD #undef XSIMPLEQ_INIT #undef XSIMPLEQ_INSERT_AFTER #undef XSIMPLEQ_INSERT_HEAD #undef XSIMPLEQ_INSERT_TAIL #undef XSIMPLEQ_NEXT #undef XSIMPLEQ_REMOVE_AFTER #undef XSIMPLEQ_REMOVE_HEAD #undef XSIMPLEQ_XOR /* * This file defines five types of data structures: singly-linked lists, * lists, simple queues, tail queues and XOR simple queues. * * * A singly-linked list is headed by a single forward pointer. The elements * are singly linked for minimum space and pointer manipulation overhead at * the expense of O(n) removal for arbitrary elements. New elements can be * added to the list after an existing element or at the head of the list. * Elements being removed from the head of the list should use the explicit * macro for this purpose for optimum efficiency. A singly-linked list may * only be traversed in the forward direction. Singly-linked lists are ideal * for applications with large datasets and few or no removals or for * implementing a LIFO queue. * * A list is headed by a single forward pointer (or an array of forward * pointers for a hash table header). The elements are doubly linked * so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before * or after an existing element or at the head of the list. A list * may only be traversed in the forward direction. * * A simple queue is headed by a pair of pointers, one to the head of the * list and the other to the tail of the list. The elements are singly * linked to save space, so elements can only be removed from the * head of the list. New elements can be added to the list before or after * an existing element, at the head of the list, or at the end of the * list. A simple queue may only be traversed in the forward direction. * * A tail queue is headed by a pair of pointers, one to the head of the * list and the other to the tail of the list. The elements are doubly * linked so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before or * after an existing element, at the head of the list, or at the end of * the list. A tail queue may be traversed in either direction. * * An XOR simple queue is used in the same way as a regular simple queue. * The difference is that the head structure also includes a "cookie" that * is XOR'd with the queue pointer (first, last or next) to generate the * real pointer value. * * For details on the use of these macros, see the queue(3) manual page. */ #if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) #define _Q_INVALID ((void *)-1) #define _Q_INVALIDATE(a) (a) = _Q_INVALID #else #define _Q_INVALIDATE(a) #endif /* * Singly-linked List definitions. */ #define SLIST_HEAD(name, type) \\ struct name { \\ struct type *slh_first; /* first element */ \\ } #define SLIST_HEAD_INITIALIZER(head) \\ { NULL } #define SLIST_ENTRY(type) \\ struct { \\ struct type *sle_next; /* next element */ \\ } /* * Singly-linked List access methods. */ #define SLIST_FIRST(head) ((head)->slh_first) #define SLIST_END(head) NULL #define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) #define SLIST_FOREACH(var, head, field) \\ for((var) = SLIST_FIRST(head); \\ (var) != SLIST_END(head); \\ (var) = SLIST_NEXT(var, field)) #define SLIST_FOREACH_SAFE(var, head, field, tvar) \\ for ((var) = SLIST_FIRST(head); \\ (var) && ((tvar) = SLIST_NEXT(var, field), 1); \\ (var) = (tvar)) /* * Singly-linked List functions. */ #define SLIST_INIT(head) { \\ SLIST_FIRST(head) = SLIST_END(head); \\ } #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \\ (elm)->field.sle_next = (slistelm)->field.sle_next; \\ (slistelm)->field.sle_next = (elm); \\ } while (0) #define SLIST_INSERT_HEAD(head, elm, field) do { \\ (elm)->field.sle_next = (head)->slh_first; \\ (head)->slh_first = (elm); \\ } while (0) #define SLIST_REMOVE_AFTER(elm, field) do { \\ (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \\ } while (0) #define SLIST_REMOVE_HEAD(head, field) do { \\ (head)->slh_first = (head)->slh_first->field.sle_next; \\ } while (0) #define SLIST_REMOVE(head, elm, type, field) do { \\ if ((head)->slh_first == (elm)) { \\ SLIST_REMOVE_HEAD((head), field); \\ } else { \\ struct type *curelm = (head)->slh_first; \\ \\ while (curelm->field.sle_next != (elm)) \\ curelm = curelm->field.sle_next; \\ curelm->field.sle_next = \\ curelm->field.sle_next->field.sle_next; \\ } \\ _Q_INVALIDATE((elm)->field.sle_next); \\ } while (0) /* * List definitions. */ #define LIST_HEAD(name, type) \\ struct name { \\ struct type *lh_first; /* first element */ \\ } #define LIST_HEAD_INITIALIZER(head) \\ { NULL } #define LIST_ENTRY(type) \\ struct { \\ struct type *le_next; /* next element */ \\ struct type **le_prev; /* address of previous next element */ \\ } /* * List access methods. */ #define LIST_FIRST(head) ((head)->lh_first) #define LIST_END(head) NULL #define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) #define LIST_NEXT(elm, field) ((elm)->field.le_next) #define LIST_FOREACH(var, head, field) \\ for((var) = LIST_FIRST(head); \\ (var)!= LIST_END(head); \\ (var) = LIST_NEXT(var, field)) #define LIST_FOREACH_SAFE(var, head, field, tvar) \\ for ((var) = LIST_FIRST(head); \\ (var) && ((tvar) = LIST_NEXT(var, field), 1); \\ (var) = (tvar)) /* * List functions. */ #define LIST_INIT(head) do { \\ LIST_FIRST(head) = LIST_END(head); \\ } while (0) #define LIST_INSERT_AFTER(listelm, elm, field) do { \\ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \\ (listelm)->field.le_next->field.le_prev = \\ &(elm)->field.le_next; \\ (listelm)->field.le_next = (elm); \\ (elm)->field.le_prev = &(listelm)->field.le_next; \\ } while (0) #define LIST_INSERT_BEFORE(listelm, elm, field) do { \\ (elm)->field.le_prev = (listelm)->field.le_prev; \\ (elm)->field.le_next = (listelm); \\ *(listelm)->field.le_prev = (elm); \\ (listelm)->field.le_prev = &(elm)->field.le_next; \\ } while (0) #define LIST_INSERT_HEAD(head, elm, field) do { \\ if (((elm)->field.le_next = (head)->lh_first) != NULL) \\ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\\ (head)->lh_first = (elm); \\ (elm)->field.le_prev = &(head)->lh_first; \\ } while (0) #define LIST_REMOVE(elm, field) do { \\ if ((elm)->field.le_next != NULL) \\ (elm)->field.le_next->field.le_prev = \\ (elm)->field.le_prev; \\ *(elm)->field.le_prev = (elm)->field.le_next; \\ _Q_INVALIDATE((elm)->field.le_prev); \\ _Q_INVALIDATE((elm)->field.le_next); \\ } while (0) #define LIST_REPLACE(elm, elm2, field) do { \\ if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \\ (elm2)->field.le_next->field.le_prev = \\ &(elm2)->field.le_next; \\ (elm2)->field.le_prev = (elm)->field.le_prev; \\ *(elm2)->field.le_prev = (elm2); \\ _Q_INVALIDATE((elm)->field.le_prev); \\ _Q_INVALIDATE((elm)->field.le_next); \\ } while (0) /* * Simple queue definitions. */ #define SIMPLEQ_HEAD(name, type) \\ struct name { \\ struct type *sqh_first; /* first element */ \\ struct type **sqh_last; /* addr of last next element */ \\ } #define SIMPLEQ_HEAD_INITIALIZER(head) \\ { NULL, &(head).sqh_first } #define SIMPLEQ_ENTRY(type) \\ struct { \\ struct type *sqe_next; /* next element */ \\ } /* * Simple queue access methods. */ #define SIMPLEQ_FIRST(head) ((head)->sqh_first) #define SIMPLEQ_END(head) NULL #define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) #define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) #define SIMPLEQ_FOREACH(var, head, field) \\ for((var) = SIMPLEQ_FIRST(head); \\ (var) != SIMPLEQ_END(head); \\ (var) = SIMPLEQ_NEXT(var, field)) #define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \\ for ((var) = SIMPLEQ_FIRST(head); \\ (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \\ (var) = (tvar)) /* * Simple queue functions. */ #define SIMPLEQ_INIT(head) do { \\ (head)->sqh_first = NULL; \\ (head)->sqh_last = &(head)->sqh_first; \\ } while (0) #define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \\ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \\ (head)->sqh_last = &(elm)->field.sqe_next; \\ (head)->sqh_first = (elm); \\ } while (0) #define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \\ (elm)->field.sqe_next = NULL; \\ *(head)->sqh_last = (elm); \\ (head)->sqh_last = &(elm)->field.sqe_next; \\ } while (0) #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \\ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\\ (head)->sqh_last = &(elm)->field.sqe_next; \\ (listelm)->field.sqe_next = (elm); \\ } while (0) #define SIMPLEQ_REMOVE_HEAD(head, field) do { \\ if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \\ (head)->sqh_last = &(head)->sqh_first; \\ } while (0) #define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \\ if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \\ == NULL) \\ (head)->sqh_last = &(elm)->field.sqe_next; \\ } while (0) #define SIMPLEQ_CONCAT(head1, head2) do { \\ if (!SIMPLEQ_EMPTY((head2))) { \\ *(head1)->sqh_last = (head2)->sqh_first; \\ (head1)->sqh_last = (head2)->sqh_last; \\ SIMPLEQ_INIT((head2)); \\ } \\ } while (0) /* * XOR Simple queue definitions. */ #define XSIMPLEQ_HEAD(name, type) \\ struct name { \\ struct type *sqx_first; /* first element */ \\ struct type **sqx_last; /* addr of last next element */ \\ unsigned long sqx_cookie; \\ } #define XSIMPLEQ_ENTRY(type) \\ struct { \\ struct type *sqx_next; /* next element */ \\ } /* * XOR Simple queue access methods. */ #define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \\ (unsigned long)(ptr))) #define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first)) #define XSIMPLEQ_END(head) NULL #define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head)) #define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next)) #define XSIMPLEQ_FOREACH(var, head, field) \\ for ((var) = XSIMPLEQ_FIRST(head); \\ (var) != XSIMPLEQ_END(head); \\ (var) = XSIMPLEQ_NEXT(head, var, field)) #define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \\ for ((var) = XSIMPLEQ_FIRST(head); \\ (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \\ (var) = (tvar)) /* * XOR Simple queue functions. */ #define XSIMPLEQ_INIT(head) do { \\ arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \\ (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \\ (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \\ } while (0) #define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \\ if (((elm)->field.sqx_next = (head)->sqx_first) == \\ XSIMPLEQ_XOR(head, NULL)) \\ (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\ (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \\ } while (0) #define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \\ (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \\ *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \\ (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\ } while (0) #define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \\ if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \\ XSIMPLEQ_XOR(head, NULL)) \\ (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\ (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \\ } while (0) #define XSIMPLEQ_REMOVE_HEAD(head, field) do { \\ if (((head)->sqx_first = XSIMPLEQ_XOR(head, \\ (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \\ (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \\ } while (0) #define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \\ if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \\ (elm)->field.sqx_next)->field.sqx_next) \\ == XSIMPLEQ_XOR(head, NULL)) \\ (head)->sqx_last = \\ XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\ } while (0) /* * Tail queue definitions. */ #define TAILQ_HEAD(name, type) \\ struct name { \\ struct type *tqh_first; /* first element */ \\ struct type **tqh_last; /* addr of last next element */ \\ } #define TAILQ_HEAD_INITIALIZER(head) \\ { NULL, &(head).tqh_first } #define TAILQ_ENTRY(type) \\ struct { \\ struct type *tqe_next; /* next element */ \\ struct type **tqe_prev; /* address of previous next element */ \\ } /* * Tail queue access methods. */ #define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_END(head) NULL #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define TAILQ_LAST(head, headname) \\ (*(((struct headname *)((head)->tqh_last))->tqh_last)) /* XXX */ #define TAILQ_PREV(elm, headname, field) \\ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) #define TAILQ_EMPTY(head) \\ (TAILQ_FIRST(head) == TAILQ_END(head)) #define TAILQ_FOREACH(var, head, field) \\ for((var) = TAILQ_FIRST(head); \\ (var) != TAILQ_END(head); \\ (var) = TAILQ_NEXT(var, field)) #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \\ for ((var) = TAILQ_FIRST(head); \\ (var) != TAILQ_END(head) && \\ ((tvar) = TAILQ_NEXT(var, field), 1); \\ (var) = (tvar)) #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \\ for((var) = TAILQ_LAST(head, headname); \\ (var) != TAILQ_END(head); \\ (var) = TAILQ_PREV(var, headname, field)) #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \\ for ((var) = TAILQ_LAST(head, headname); \\ (var) != TAILQ_END(head) && \\ ((tvar) = TAILQ_PREV(var, headname, field), 1); \\ (var) = (tvar)) /* * Tail queue functions. */ #define TAILQ_INIT(head) do { \\ (head)->tqh_first = NULL; \\ (head)->tqh_last = &(head)->tqh_first; \\ } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \\ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \\ (head)->tqh_first->field.tqe_prev = \\ &(elm)->field.tqe_next; \\ else \\ (head)->tqh_last = &(elm)->field.tqe_next; \\ (head)->tqh_first = (elm); \\ (elm)->field.tqe_prev = &(head)->tqh_first; \\ } while (0) #define TAILQ_INSERT_TAIL(head, elm, field) do { \\ (elm)->field.tqe_next = NULL; \\ (elm)->field.tqe_prev = (head)->tqh_last; \\ *(head)->tqh_last = (elm); \\ (head)->tqh_last = &(elm)->field.tqe_next; \\ } while (0) #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \\ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\\ (elm)->field.tqe_next->field.tqe_prev = \\ &(elm)->field.tqe_next; \\ else \\ (head)->tqh_last = &(elm)->field.tqe_next; \\ (listelm)->field.tqe_next = (elm); \\ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \\ } while (0) #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \\ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \\ (elm)->field.tqe_next = (listelm); \\ *(listelm)->field.tqe_prev = (elm); \\ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \\ } while (0) #define TAILQ_REMOVE(head, elm, field) do { \\ if (((elm)->field.tqe_next) != NULL) \\ (elm)->field.tqe_next->field.tqe_prev = \\ (elm)->field.tqe_prev; \\ else \\ (head)->tqh_last = (elm)->field.tqe_prev; \\ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \\ _Q_INVALIDATE((elm)->field.tqe_prev); \\ _Q_INVALIDATE((elm)->field.tqe_next); \\ } while (0) #define TAILQ_REPLACE(head, elm, elm2, field) do { \\ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \\ (elm2)->field.tqe_next->field.tqe_prev = \\ &(elm2)->field.tqe_next; \\ else \\ (head)->tqh_last = &(elm2)->field.tqe_next; \\ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \\ *(elm2)->field.tqe_prev = (elm2); \\ _Q_INVALIDATE((elm)->field.tqe_prev); \\ _Q_INVALIDATE((elm)->field.tqe_next); \\ } while (0) #define TAILQ_CONCAT(head1, head2, field) do { \\ if (!TAILQ_EMPTY(head2)) { \\ *(head1)->tqh_last = (head2)->tqh_first; \\ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \\ (head1)->tqh_last = (head2)->tqh_last; \\ TAILQ_INIT((head2)); \\ } \\ } while (0) __HEREDOC__ fi if [ ${HAVE_SYS_TREE} -eq 0 ]; then cat << __HEREDOC__ /* * A compatible version of OpenBSD . */ /* * Copyright 2002 Niels Provos * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR 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. */ /* OPENBSD ORIGINAL: sys/sys/tree.h */ /* * This file defines data structures for different types of trees: * splay trees and red-black trees. * * A splay tree is a self-organizing data structure. Every operation * on the tree causes a splay to happen. The splay moves the requested * node to the root of the tree and partly rebalances it. * * This has the benefit that request locality causes faster lookups as * the requested nodes move to the top of the tree. On the other hand, * every lookup causes memory writes. * * The Balance Theorem bounds the total access time for m operations * and n inserts on an initially empty tree as O((m + n)lg n). The * amortized cost for a sequence of m accesses to a splay tree is O(lg n); * * A red-black tree is a binary search tree with the node color as an * extra attribute. It fulfills a set of conditions: * - every search path from the root to a leaf consists of the * same number of black nodes, * - each red node (except for the root) has a black parent, * - each leaf node is black. * * Every operation on a red-black tree is bounded as O(lg n). * The maximum height of a red-black tree is 2lg (n+1). */ #define SPLAY_HEAD(name, type) \\ struct name { \\ struct type *sph_root; /* root of the tree */ \\ } #define SPLAY_INITIALIZER(root) \\ { NULL } #define SPLAY_INIT(root) do { \\ (root)->sph_root = NULL; \\ } while (0) #define SPLAY_ENTRY(type) \\ struct { \\ struct type *spe_left; /* left element */ \\ struct type *spe_right; /* right element */ \\ } #define SPLAY_LEFT(elm, field) (elm)->field.spe_left #define SPLAY_RIGHT(elm, field) (elm)->field.spe_right #define SPLAY_ROOT(head) (head)->sph_root #define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ #define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \\ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \\ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \\ (head)->sph_root = tmp; \\ } while (0) #define SPLAY_ROTATE_LEFT(head, tmp, field) do { \\ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \\ SPLAY_LEFT(tmp, field) = (head)->sph_root; \\ (head)->sph_root = tmp; \\ } while (0) #define SPLAY_LINKLEFT(head, tmp, field) do { \\ SPLAY_LEFT(tmp, field) = (head)->sph_root; \\ tmp = (head)->sph_root; \\ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \\ } while (0) #define SPLAY_LINKRIGHT(head, tmp, field) do { \\ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \\ tmp = (head)->sph_root; \\ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \\ } while (0) #define SPLAY_ASSEMBLE(head, node, left, right, field) do { \\ SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \\ SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\\ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \\ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \\ } while (0) /* Generates prototypes and inline functions */ #define SPLAY_PROTOTYPE(name, type, field, cmp) \\ void name##_SPLAY(struct name *, struct type *); \\ void name##_SPLAY_MINMAX(struct name *, int); \\ struct type *name##_SPLAY_INSERT(struct name *, struct type *); \\ struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \\ \\ /* Finds the node with the same key as elm */ \\ static __inline struct type * \\ name##_SPLAY_FIND(struct name *head, struct type *elm) \\ { \\ if (SPLAY_EMPTY(head)) \\ return(NULL); \\ name##_SPLAY(head, elm); \\ if ((cmp)(elm, (head)->sph_root) == 0) \\ return (head->sph_root); \\ return (NULL); \\ } \\ \\ static __inline struct type * \\ name##_SPLAY_NEXT(struct name *head, struct type *elm) \\ { \\ name##_SPLAY(head, elm); \\ if (SPLAY_RIGHT(elm, field) != NULL) { \\ elm = SPLAY_RIGHT(elm, field); \\ while (SPLAY_LEFT(elm, field) != NULL) { \\ elm = SPLAY_LEFT(elm, field); \\ } \\ } else \\ elm = NULL; \\ return (elm); \\ } \\ \\ static __inline struct type * \\ name##_SPLAY_MIN_MAX(struct name *head, int val) \\ { \\ name##_SPLAY_MINMAX(head, val); \\ return (SPLAY_ROOT(head)); \\ } /* Main splay operation. * Moves node close to the key of elm to top */ #define SPLAY_GENERATE(name, type, field, cmp) \\ struct type * \\ name##_SPLAY_INSERT(struct name *head, struct type *elm) \\ { \\ if (SPLAY_EMPTY(head)) { \\ SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \\ } else { \\ int __comp; \\ name##_SPLAY(head, elm); \\ __comp = (cmp)(elm, (head)->sph_root); \\ if(__comp < 0) { \\ SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\\ SPLAY_RIGHT(elm, field) = (head)->sph_root; \\ SPLAY_LEFT((head)->sph_root, field) = NULL; \\ } else if (__comp > 0) { \\ SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\\ SPLAY_LEFT(elm, field) = (head)->sph_root; \\ SPLAY_RIGHT((head)->sph_root, field) = NULL; \\ } else \\ return ((head)->sph_root); \\ } \\ (head)->sph_root = (elm); \\ return (NULL); \\ } \\ \\ struct type * \\ name##_SPLAY_REMOVE(struct name *head, struct type *elm) \\ { \\ struct type *__tmp; \\ if (SPLAY_EMPTY(head)) \\ return (NULL); \\ name##_SPLAY(head, elm); \\ if ((cmp)(elm, (head)->sph_root) == 0) { \\ if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \\ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\\ } else { \\ __tmp = SPLAY_RIGHT((head)->sph_root, field); \\ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\\ name##_SPLAY(head, elm); \\ SPLAY_RIGHT((head)->sph_root, field) = __tmp; \\ } \\ return (elm); \\ } \\ return (NULL); \\ } \\ \\ void \\ name##_SPLAY(struct name *head, struct type *elm) \\ { \\ struct type __node, *__left, *__right, *__tmp; \\ int __comp; \\ \\ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\\ __left = __right = &__node; \\ \\ while ((__comp = (cmp)(elm, (head)->sph_root))) { \\ if (__comp < 0) { \\ __tmp = SPLAY_LEFT((head)->sph_root, field); \\ if (__tmp == NULL) \\ break; \\ if ((cmp)(elm, __tmp) < 0){ \\ SPLAY_ROTATE_RIGHT(head, __tmp, field); \\ if (SPLAY_LEFT((head)->sph_root, field) == NULL)\\ break; \\ } \\ SPLAY_LINKLEFT(head, __right, field); \\ } else if (__comp > 0) { \\ __tmp = SPLAY_RIGHT((head)->sph_root, field); \\ if (__tmp == NULL) \\ break; \\ if ((cmp)(elm, __tmp) > 0){ \\ SPLAY_ROTATE_LEFT(head, __tmp, field); \\ if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\\ break; \\ } \\ SPLAY_LINKRIGHT(head, __left, field); \\ } \\ } \\ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \\ } \\ \\ /* Splay with either the minimum or the maximum element \\ * Used to find minimum or maximum element in tree. \\ */ \\ void name##_SPLAY_MINMAX(struct name *head, int __comp) \\ { \\ struct type __node, *__left, *__right, *__tmp; \\ \\ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\\ __left = __right = &__node; \\ \\ while (1) { \\ if (__comp < 0) { \\ __tmp = SPLAY_LEFT((head)->sph_root, field); \\ if (__tmp == NULL) \\ break; \\ if (__comp < 0){ \\ SPLAY_ROTATE_RIGHT(head, __tmp, field); \\ if (SPLAY_LEFT((head)->sph_root, field) == NULL)\\ break; \\ } \\ SPLAY_LINKLEFT(head, __right, field); \\ } else if (__comp > 0) { \\ __tmp = SPLAY_RIGHT((head)->sph_root, field); \\ if (__tmp == NULL) \\ break; \\ if (__comp > 0) { \\ SPLAY_ROTATE_LEFT(head, __tmp, field); \\ if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\\ break; \\ } \\ SPLAY_LINKRIGHT(head, __left, field); \\ } \\ } \\ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \\ } #define SPLAY_NEGINF -1 #define SPLAY_INF 1 #define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) #define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) #define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) #define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) #define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \\ : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) #define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \\ : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) #define SPLAY_FOREACH(x, name, head) \\ for ((x) = SPLAY_MIN(name, head); \\ (x) != NULL; \\ (x) = SPLAY_NEXT(name, head, x)) /* Macros that define a red-black tree */ #define RB_HEAD(name, type) \\ struct name { \\ struct type *rbh_root; /* root of the tree */ \\ } #define RB_INITIALIZER(root) \\ { NULL } #define RB_INIT(root) do { \\ (root)->rbh_root = NULL; \\ } while (0) #define RB_BLACK 0 #define RB_RED 1 #define RB_ENTRY(type) \\ struct { \\ struct type *rbe_left; /* left element */ \\ struct type *rbe_right; /* right element */ \\ struct type *rbe_parent; /* parent element */ \\ int rbe_color; /* node color */ \\ } #define RB_LEFT(elm, field) (elm)->field.rbe_left #define RB_RIGHT(elm, field) (elm)->field.rbe_right #define RB_PARENT(elm, field) (elm)->field.rbe_parent #define RB_COLOR(elm, field) (elm)->field.rbe_color #define RB_ROOT(head) (head)->rbh_root #define RB_EMPTY(head) (RB_ROOT(head) == NULL) #define RB_SET(elm, parent, field) do { \\ RB_PARENT(elm, field) = parent; \\ RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \\ RB_COLOR(elm, field) = RB_RED; \\ } while (0) #define RB_SET_BLACKRED(black, red, field) do { \\ RB_COLOR(black, field) = RB_BLACK; \\ RB_COLOR(red, field) = RB_RED; \\ } while (0) #ifndef RB_AUGMENT #define RB_AUGMENT(x) do {} while (0) #endif #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \\ (tmp) = RB_RIGHT(elm, field); \\ if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \\ RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \\ } \\ RB_AUGMENT(elm); \\ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \\ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \\ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \\ else \\ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \\ } else \\ (head)->rbh_root = (tmp); \\ RB_LEFT(tmp, field) = (elm); \\ RB_PARENT(elm, field) = (tmp); \\ RB_AUGMENT(tmp); \\ if ((RB_PARENT(tmp, field))) \\ RB_AUGMENT(RB_PARENT(tmp, field)); \\ } while (0) #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \\ (tmp) = RB_LEFT(elm, field); \\ if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \\ RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \\ } \\ RB_AUGMENT(elm); \\ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \\ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \\ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \\ else \\ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \\ } else \\ (head)->rbh_root = (tmp); \\ RB_RIGHT(tmp, field) = (elm); \\ RB_PARENT(elm, field) = (tmp); \\ RB_AUGMENT(tmp); \\ if ((RB_PARENT(tmp, field))) \\ RB_AUGMENT(RB_PARENT(tmp, field)); \\ } while (0) /* Generates prototypes and inline functions */ #define RB_PROTOTYPE(name, type, field, cmp) \\ RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) #define RB_PROTOTYPE_STATIC(name, type, field, cmp) \\ RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \\ attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \\ attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\\ attr struct type *name##_RB_REMOVE(struct name *, struct type *); \\ attr struct type *name##_RB_INSERT(struct name *, struct type *); \\ attr struct type *name##_RB_FIND(struct name *, struct type *); \\ attr struct type *name##_RB_NFIND(struct name *, struct type *); \\ attr struct type *name##_RB_NEXT(struct type *); \\ attr struct type *name##_RB_PREV(struct type *); \\ attr struct type *name##_RB_MINMAX(struct name *, int); \\ \\ /* Main rb operation. * Moves node close to the key of elm to top */ #define RB_GENERATE(name, type, field, cmp) \\ RB_GENERATE_INTERNAL(name, type, field, cmp,) #define RB_GENERATE_STATIC(name, type, field, cmp) \\ RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \\ attr void \\ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \\ { \\ struct type *parent, *gparent, *tmp; \\ while ((parent = RB_PARENT(elm, field)) && \\ RB_COLOR(parent, field) == RB_RED) { \\ gparent = RB_PARENT(parent, field); \\ if (parent == RB_LEFT(gparent, field)) { \\ tmp = RB_RIGHT(gparent, field); \\ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \\ RB_COLOR(tmp, field) = RB_BLACK; \\ RB_SET_BLACKRED(parent, gparent, field);\\ elm = gparent; \\ continue; \\ } \\ if (RB_RIGHT(parent, field) == elm) { \\ RB_ROTATE_LEFT(head, parent, tmp, field);\\ tmp = parent; \\ parent = elm; \\ elm = tmp; \\ } \\ RB_SET_BLACKRED(parent, gparent, field); \\ RB_ROTATE_RIGHT(head, gparent, tmp, field); \\ } else { \\ tmp = RB_LEFT(gparent, field); \\ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \\ RB_COLOR(tmp, field) = RB_BLACK; \\ RB_SET_BLACKRED(parent, gparent, field);\\ elm = gparent; \\ continue; \\ } \\ if (RB_LEFT(parent, field) == elm) { \\ RB_ROTATE_RIGHT(head, parent, tmp, field);\\ tmp = parent; \\ parent = elm; \\ elm = tmp; \\ } \\ RB_SET_BLACKRED(parent, gparent, field); \\ RB_ROTATE_LEFT(head, gparent, tmp, field); \\ } \\ } \\ RB_COLOR(head->rbh_root, field) = RB_BLACK; \\ } \\ \\ attr void \\ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \\ { \\ struct type *tmp; \\ while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \\ elm != RB_ROOT(head)) { \\ if (RB_LEFT(parent, field) == elm) { \\ tmp = RB_RIGHT(parent, field); \\ if (RB_COLOR(tmp, field) == RB_RED) { \\ RB_SET_BLACKRED(tmp, parent, field); \\ RB_ROTATE_LEFT(head, parent, tmp, field);\\ tmp = RB_RIGHT(parent, field); \\ } \\ if ((RB_LEFT(tmp, field) == NULL || \\ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\\ (RB_RIGHT(tmp, field) == NULL || \\ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\\ RB_COLOR(tmp, field) = RB_RED; \\ elm = parent; \\ parent = RB_PARENT(elm, field); \\ } else { \\ if (RB_RIGHT(tmp, field) == NULL || \\ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\\ struct type *oleft; \\ if ((oleft = RB_LEFT(tmp, field)))\\ RB_COLOR(oleft, field) = RB_BLACK;\\ RB_COLOR(tmp, field) = RB_RED; \\ RB_ROTATE_RIGHT(head, tmp, oleft, field);\\ tmp = RB_RIGHT(parent, field); \\ } \\ RB_COLOR(tmp, field) = RB_COLOR(parent, field);\\ RB_COLOR(parent, field) = RB_BLACK; \\ if (RB_RIGHT(tmp, field)) \\ RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\\ RB_ROTATE_LEFT(head, parent, tmp, field);\\ elm = RB_ROOT(head); \\ break; \\ } \\ } else { \\ tmp = RB_LEFT(parent, field); \\ if (RB_COLOR(tmp, field) == RB_RED) { \\ RB_SET_BLACKRED(tmp, parent, field); \\ RB_ROTATE_RIGHT(head, parent, tmp, field);\\ tmp = RB_LEFT(parent, field); \\ } \\ if ((RB_LEFT(tmp, field) == NULL || \\ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\\ (RB_RIGHT(tmp, field) == NULL || \\ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\\ RB_COLOR(tmp, field) = RB_RED; \\ elm = parent; \\ parent = RB_PARENT(elm, field); \\ } else { \\ if (RB_LEFT(tmp, field) == NULL || \\ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\\ struct type *oright; \\ if ((oright = RB_RIGHT(tmp, field)))\\ RB_COLOR(oright, field) = RB_BLACK;\\ RB_COLOR(tmp, field) = RB_RED; \\ RB_ROTATE_LEFT(head, tmp, oright, field);\\ tmp = RB_LEFT(parent, field); \\ } \\ RB_COLOR(tmp, field) = RB_COLOR(parent, field);\\ RB_COLOR(parent, field) = RB_BLACK; \\ if (RB_LEFT(tmp, field)) \\ RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\\ RB_ROTATE_RIGHT(head, parent, tmp, field);\\ elm = RB_ROOT(head); \\ break; \\ } \\ } \\ } \\ if (elm) \\ RB_COLOR(elm, field) = RB_BLACK; \\ } \\ \\ attr struct type * \\ name##_RB_REMOVE(struct name *head, struct type *elm) \\ { \\ struct type *child, *parent, *old = elm; \\ int color; \\ if (RB_LEFT(elm, field) == NULL) \\ child = RB_RIGHT(elm, field); \\ else if (RB_RIGHT(elm, field) == NULL) \\ child = RB_LEFT(elm, field); \\ else { \\ struct type *left; \\ elm = RB_RIGHT(elm, field); \\ while ((left = RB_LEFT(elm, field))) \\ elm = left; \\ child = RB_RIGHT(elm, field); \\ parent = RB_PARENT(elm, field); \\ color = RB_COLOR(elm, field); \\ if (child) \\ RB_PARENT(child, field) = parent; \\ if (parent) { \\ if (RB_LEFT(parent, field) == elm) \\ RB_LEFT(parent, field) = child; \\ else \\ RB_RIGHT(parent, field) = child; \\ RB_AUGMENT(parent); \\ } else \\ RB_ROOT(head) = child; \\ if (RB_PARENT(elm, field) == old) \\ parent = elm; \\ (elm)->field = (old)->field; \\ if (RB_PARENT(old, field)) { \\ if (RB_LEFT(RB_PARENT(old, field), field) == old)\\ RB_LEFT(RB_PARENT(old, field), field) = elm;\\ else \\ RB_RIGHT(RB_PARENT(old, field), field) = elm;\\ RB_AUGMENT(RB_PARENT(old, field)); \\ } else \\ RB_ROOT(head) = elm; \\ RB_PARENT(RB_LEFT(old, field), field) = elm; \\ if (RB_RIGHT(old, field)) \\ RB_PARENT(RB_RIGHT(old, field), field) = elm; \\ if (parent) { \\ left = parent; \\ do { \\ RB_AUGMENT(left); \\ } while ((left = RB_PARENT(left, field))); \\ } \\ goto color; \\ } \\ parent = RB_PARENT(elm, field); \\ color = RB_COLOR(elm, field); \\ if (child) \\ RB_PARENT(child, field) = parent; \\ if (parent) { \\ if (RB_LEFT(parent, field) == elm) \\ RB_LEFT(parent, field) = child; \\ else \\ RB_RIGHT(parent, field) = child; \\ RB_AUGMENT(parent); \\ } else \\ RB_ROOT(head) = child; \\ color: \\ if (color == RB_BLACK) \\ name##_RB_REMOVE_COLOR(head, parent, child); \\ return (old); \\ } \\ \\ /* Inserts a node into the RB tree */ \\ attr struct type * \\ name##_RB_INSERT(struct name *head, struct type *elm) \\ { \\ struct type *tmp; \\ struct type *parent = NULL; \\ int comp = 0; \\ tmp = RB_ROOT(head); \\ while (tmp) { \\ parent = tmp; \\ comp = (cmp)(elm, parent); \\ if (comp < 0) \\ tmp = RB_LEFT(tmp, field); \\ else if (comp > 0) \\ tmp = RB_RIGHT(tmp, field); \\ else \\ return (tmp); \\ } \\ RB_SET(elm, parent, field); \\ if (parent != NULL) { \\ if (comp < 0) \\ RB_LEFT(parent, field) = elm; \\ else \\ RB_RIGHT(parent, field) = elm; \\ RB_AUGMENT(parent); \\ } else \\ RB_ROOT(head) = elm; \\ name##_RB_INSERT_COLOR(head, elm); \\ return (NULL); \\ } \\ \\ /* Finds the node with the same key as elm */ \\ attr struct type * \\ name##_RB_FIND(struct name *head, struct type *elm) \\ { \\ struct type *tmp = RB_ROOT(head); \\ int comp; \\ while (tmp) { \\ comp = cmp(elm, tmp); \\ if (comp < 0) \\ tmp = RB_LEFT(tmp, field); \\ else if (comp > 0) \\ tmp = RB_RIGHT(tmp, field); \\ else \\ return (tmp); \\ } \\ return (NULL); \\ } \\ \\ /* Finds the first node greater than or equal to the search key */ \\ attr struct type * \\ name##_RB_NFIND(struct name *head, struct type *elm) \\ { \\ struct type *tmp = RB_ROOT(head); \\ struct type *res = NULL; \\ int comp; \\ while (tmp) { \\ comp = cmp(elm, tmp); \\ if (comp < 0) { \\ res = tmp; \\ tmp = RB_LEFT(tmp, field); \\ } \\ else if (comp > 0) \\ tmp = RB_RIGHT(tmp, field); \\ else \\ return (tmp); \\ } \\ return (res); \\ } \\ \\ /* ARGSUSED */ \\ attr struct type * \\ name##_RB_NEXT(struct type *elm) \\ { \\ if (RB_RIGHT(elm, field)) { \\ elm = RB_RIGHT(elm, field); \\ while (RB_LEFT(elm, field)) \\ elm = RB_LEFT(elm, field); \\ } else { \\ if (RB_PARENT(elm, field) && \\ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \\ elm = RB_PARENT(elm, field); \\ else { \\ while (RB_PARENT(elm, field) && \\ (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\\ elm = RB_PARENT(elm, field); \\ elm = RB_PARENT(elm, field); \\ } \\ } \\ return (elm); \\ } \\ \\ /* ARGSUSED */ \\ attr struct type * \\ name##_RB_PREV(struct type *elm) \\ { \\ if (RB_LEFT(elm, field)) { \\ elm = RB_LEFT(elm, field); \\ while (RB_RIGHT(elm, field)) \\ elm = RB_RIGHT(elm, field); \\ } else { \\ if (RB_PARENT(elm, field) && \\ (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \\ elm = RB_PARENT(elm, field); \\ else { \\ while (RB_PARENT(elm, field) && \\ (elm == RB_LEFT(RB_PARENT(elm, field), field)))\\ elm = RB_PARENT(elm, field); \\ elm = RB_PARENT(elm, field); \\ } \\ } \\ return (elm); \\ } \\ \\ attr struct type * \\ name##_RB_MINMAX(struct name *head, int val) \\ { \\ struct type *tmp = RB_ROOT(head); \\ struct type *parent = NULL; \\ while (tmp) { \\ parent = tmp; \\ if (val < 0) \\ tmp = RB_LEFT(tmp, field); \\ else \\ tmp = RB_RIGHT(tmp, field); \\ } \\ return (parent); \\ } #define RB_NEGINF -1 #define RB_INF 1 #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) #define RB_FIND(name, x, y) name##_RB_FIND(x, y) #define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) #define RB_NEXT(name, x, y) name##_RB_NEXT(y) #define RB_PREV(name, x, y) name##_RB_PREV(y) #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) #define RB_FOREACH(x, name, head) \\ for ((x) = RB_MIN(name, head); \\ (x) != NULL; \\ (x) = name##_RB_NEXT(x)) #define RB_FOREACH_SAFE(x, name, head, y) \\ for ((x) = RB_MIN(name, head); \\ ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \\ (x) = (y)) #define RB_FOREACH_REVERSE(x, name, head) \\ for ((x) = RB_MAX(name, head); \\ (x) != NULL; \\ (x) = name##_RB_PREV(x)) #define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \\ for ((x) = RB_MAX(name, head); \\ ((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \\ (x) = (y)) __HEREDOC__ fi if [ ${HAVE_FTS} -eq 0 ]; then cat << __HEREDOC__ /* * Compatibility for fts(3) functions. */ typedef struct { struct _ftsent *fts_cur; /* current node */ struct _ftsent *fts_child; /* linked list of children */ struct _ftsent **fts_array; /* sort array */ dev_t fts_dev; /* starting device # */ char *fts_path; /* path for this descent */ int fts_rfd; /* fd for root */ size_t fts_pathlen; /* sizeof(path) */ int fts_nitems; /* elements in the sort array */ int (*fts_compar)(const struct _ftsent **, const struct _ftsent **); /* compare function */ #define FTS_COMFOLLOW 0x0001 /* follow command line symlinks */ #define FTS_LOGICAL 0x0002 /* logical walk */ #define FTS_NOCHDIR 0x0004 /* don't change directories */ #define FTS_NOSTAT 0x0008 /* don't get stat info */ #define FTS_PHYSICAL 0x0010 /* physical walk */ #define FTS_SEEDOT 0x0020 /* return dot and dot-dot */ #define FTS_XDEV 0x0040 /* don't cross devices */ #define FTS_OPTIONMASK 0x00ff /* valid user option mask */ #define FTS_NAMEONLY 0x1000 /* (private) child names only */ #define FTS_STOP 0x2000 /* (private) unrecoverable error */ int fts_options; /* fts_open options, global flags */ } FTS; typedef struct _ftsent { struct _ftsent *fts_cycle; /* cycle node */ struct _ftsent *fts_parent; /* parent directory */ struct _ftsent *fts_link; /* next file in directory */ long fts_number; /* local numeric value */ void *fts_pointer; /* local address value */ char *fts_accpath; /* access path */ char *fts_path; /* root path */ int fts_errno; /* errno for this node */ int fts_symfd; /* fd for symlink */ size_t fts_pathlen; /* strlen(fts_path) */ size_t fts_namelen; /* strlen(fts_name) */ ino_t fts_ino; /* inode */ dev_t fts_dev; /* device */ nlink_t fts_nlink; /* link count */ #define FTS_ROOTPARENTLEVEL -1 #define FTS_ROOTLEVEL 0 #define FTS_MAXLEVEL 0x7fffffff int fts_level; /* depth (-1 to N) */ #define FTS_D 1 /* preorder directory */ #define FTS_DC 2 /* directory that causes cycles */ #define FTS_DEFAULT 3 /* none of the above */ #define FTS_DNR 4 /* unreadable directory */ #define FTS_DOT 5 /* dot or dot-dot */ #define FTS_DP 6 /* postorder directory */ #define FTS_ERR 7 /* error; errno is set */ #define FTS_F 8 /* regular file */ #define FTS_INIT 9 /* initialized only */ #define FTS_NS 10 /* stat(2) failed */ #define FTS_NSOK 11 /* no stat(2) requested */ #define FTS_SL 12 /* symbolic link */ #define FTS_SLNONE 13 /* symbolic link without target */ unsigned short fts_info; /* user flags for FTSENT structure */ #define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */ #define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */ unsigned short fts_flags; /* private flags for FTSENT structure */ #define FTS_AGAIN 1 /* read node again */ #define FTS_FOLLOW 2 /* follow symbolic link */ #define FTS_NOINSTR 3 /* no instructions */ #define FTS_SKIP 4 /* discard node */ unsigned short fts_instr; /* fts_set() instructions */ unsigned short fts_spare; /* unused */ struct stat *fts_statp; /* stat(2) information */ char fts_name[1]; /* file name */ } FTSENT; FTSENT *fts_children(FTS *, int); int fts_close(FTS *); FTS *fts_open(char * const *, int, int (*)(const FTSENT **, const FTSENT **)); FTSENT *fts_read(FTS *); int fts_set(FTS *, FTSENT *, int); __HEREDOC__ fi cat << __HEREDOC__ #endif /*!OCONFIGURE_CONFIG_H*/ __HEREDOC__ echo "config.h: written" 1>&2 echo "config.h: written" 1>&3 #---------------------------------------------------------------------- # Now we go to generate our Makefile.configure. # This file is simply a bunch of Makefile variables. # They'll work in both GNUmakefile and BSDmakefile. # You MIGHT want to change this. #---------------------------------------------------------------------- exec > Makefile.configure [ -z "${BINDIR}" ] && BINDIR="${PREFIX}/bin" [ -z "${SBINDIR}" ] && SBINDIR="${PREFIX}/sbin" [ -z "${INCLUDEDIR}" ] && INCLUDEDIR="${PREFIX}/include" [ -z "${LIBDIR}" ] && LIBDIR="${PREFIX}/lib" [ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man" [ -z "${SHAREDIR}" ] && SHAREDIR="${PREFIX}/share" [ -z "${INSTALL_PROGRAM}" ] && INSTALL_PROGRAM="${INSTALL} -m 0555" [ -z "${INSTALL_LIB}" ] && INSTALL_LIB="${INSTALL} -m 0444" [ -z "${INSTALL_MAN}" ] && INSTALL_MAN="${INSTALL} -m 0444" [ -z "${INSTALL_DATA}" ] && INSTALL_DATA="${INSTALL} -m 0444" cat << __HEREDOC__ AR = ${AR} CC = ${CC} CFLAGS = ${CFLAGS} CPPFLAGS = ${CPPFLAGS} LDLIBS = ${LDLIBS} LDADD = ${LDADD} LDADD_B64_NTOP = ${LDADD_B64_NTOP} LDADD_CRYPT = ${LDADD_CRYPT} LDADD_LIB_SOCKET = ${LDADD_LIB_SOCKET} LDADD_MD5 = ${LDADD_MD5} LDADD_SHA2 = ${LDADD_SHA2} LDADD_SCAN_SCALED= ${LDADD_SCAN_SCALED} LDADD_STATIC = ${LDADD_STATIC} LDFLAGS = ${LDFLAGS} LINKER_SONAME = ${LINKER_SONAME} STATIC = ${STATIC} PREFIX = ${PREFIX} BINDIR = ${BINDIR} SHAREDIR = ${SHAREDIR} SBINDIR = ${SBINDIR} INCLUDEDIR = ${INCLUDEDIR} LIBDIR = ${LIBDIR} MANDIR = ${MANDIR} INSTALL = ${INSTALL} INSTALL_PROGRAM = ${INSTALL_PROGRAM} INSTALL_LIB = ${INSTALL_LIB} INSTALL_MAN = ${INSTALL_MAN} INSTALL_DATA = ${INSTALL_DATA} __HEREDOC__ echo "Makefile.configure: written" 1>&2 echo "Makefile.configure: written" 1>&3 exit 0