commit 80189b3a48a42c30d6337897ee358b817baefd35 from: Omar Polo date: Sat Aug 13 15:39:56 2022 UTC init portable version commit - 9ae1b92da58a0a52ae079e76ef9446fa8fdba319 commit + 80189b3a48a42c30d6337897ee358b817baefd35 blob - /dev/null blob + c4d789fb1660c5c224da0864e9c5a34454172e03 (mode 644) --- /dev/null +++ .gitignore @@ -0,0 +1,9 @@ +Makefile.configure +config.h +config.h.old +config.log +config.log.old +slowcgi +*.o +*.sha256 +*.tar.gz blob - 9a0f8b5656d10fd09e62691a5ca827d357f1ff7a blob + d7c38e014ec0c89d9c8e9751144c3b6b9dbc2797 --- slowcgi.c +++ slowcgi.c @@ -16,19 +16,18 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "config.h" + #include #include -#include #include #include #include #include #include #include -#include #include #include -#include #include #include #include blob - /dev/null blob + ececb0ebf2fb2b594933a1133f6a69841e02c26a (mode 644) --- /dev/null +++ Makefile @@ -0,0 +1,61 @@ +.PHONY: all clean distclean install + +# Follow the OpenBSD release scheme. +VERSION = 7.2-beta0 +PROG = slowcgi +DISTNAME = ${PROG}-${VERSION} + +SOURCES = compats.c \ + slowcgi.c + +OBJS = ${SOURCES:.c=.o} + +DISTFILES = Makefile \ + configure \ + queue.h \ + slowcgi.8 \ + ${SOURCES} \ + tests.c + +all: ${PROG} + +Makefile.configure config.h: configure tests.c + @echo "$@ is out of date; please run ./configure" + @exit + +include Makefile.configure + +# -- targets -- + +${PROG}: ${OBJS} + ${CC} -o $@ ${OBJS} ${LDFLAGS} ${LDADD} + +clean: + rm -f ${OBJS} ${PROG} + +distclean: clean + rm -f Makefile.configure config.h config.h.old config.log config.log.old + +install: ${PROG} + mkdir -p ${DESTDIR}${BINDIR} + mkdir -p ${DESTDIR}${MANDIR}/man1 + ${INSTALL_PROGRAM} ${PROG} ${DESTDIR}${BINDIR} + ${INSTALL_MAN} slowcgi.8 ${DESTDIR}${MANDIR}/man8/${PROG}.8 + +uninstall: + rm ${DESTDIR}${BINDIR}/${PROG} + rm ${DESTDIR}${MANDIR}/man8/${PROG}.8 + +# -- maintainer targets -- + +dist: ${DISTNAME}.sha256 + +${DISTNAME}.sha256: ${DISTNAME}.tar.gz + sha256 ${DISTNAME}.tar.gz > $@ + +${DISTNAME}.tar.gz: ${DISTFILES} + mkdir -p .dist/${DISTNAME} + ${INSTALL} -m 0644 ${DISTFILES} .dist/${DISTNAME} + chmod 755 .dist/${DISTNAME}/configure + cd .dist && tar zcf ../$@ ${DISTNAME} + rm -rf .dist blob - /dev/null blob + 5b43c800abb1188de6812d0b4648b621b22c1cee (mode 644) --- /dev/null +++ README.md @@ -0,0 +1,38 @@ +# slowcgi-portable + +This is an **unofficial** portable version of [slowcgi(8)][slowcgi], a +FastCGI to CGI wrapper server. It's intended to ship with as little +changes as possible to allow it to compile and work on a variety of +systems and otherwise follow closely the development in the OpenBSD +src tree. All portable-specific commits have the "portable:" prefix +in the log message. + +[slowcgi]: https://man.openbsd.org/slowcgi + +The versioning scheme follows the OpenBSD one, that's why the first +version is 7.2. + +## Building + +The dependencies are: + + - libevent + +and optionally pkg-config. + +To build, issue: + + $ ./configure + $ make + # make install # eventually + +The build can be customized by passing arguments to the configure +script or by using a `configure.local` file; see `./configure -h` and +[`configure.local.example`](configure.local.example) for more +information. + +For Linux users with libbsd installed, the configure script can be +instructed to use libbsd as follows: + + CFLAGS="$(pkg-config --cflags libbsd-overlay)" \ + ./configure LDFLAGS="$(pkg-config --libs libbsd-overlay)" blob - /dev/null blob + 5dc288d4f3078dc8ed1143e097698e128ae84844 (mode 644) --- /dev/null +++ compats.c @@ -0,0 +1,556 @@ +#include "config.h" +#if !HAVE_ERR +/* + * Copyright (c) 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. + */ + +#include +#include +#include +#include +#include + +void +vwarnx(const char *fmt, va_list ap) +{ + fprintf(stderr, "%s: ", getprogname()); + if (fmt != NULL) + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); +} + +void +vwarnc(int code, const char *fmt, va_list ap) +{ + fprintf(stderr, "%s: ", getprogname()); + if (fmt != NULL) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": "); + } + fprintf(stderr, "%s\n", strerror(code)); +} + +void +vwarn(const char *fmt, va_list ap) +{ + int sverrno; + + sverrno = errno; + fprintf(stderr, "%s: ", getprogname()); + if (fmt != NULL) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": "); + } + fprintf(stderr, "%s\n", strerror(sverrno)); +} + +void +verrc(int eval, int code, const char *fmt, va_list ap) +{ + fprintf(stderr, "%s: ", getprogname()); + if (fmt != NULL) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": "); + } + fprintf(stderr, "%s\n", strerror(code)); + exit(eval); +} + +void +verrx(int eval, const char *fmt, va_list ap) +{ + fprintf(stderr, "%s: ", getprogname()); + if (fmt != NULL) + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + exit(eval); +} + +void +verr(int eval, const char *fmt, va_list ap) +{ + int sverrno; + + sverrno = errno; + fprintf(stderr, "%s: ", getprogname()); + if (fmt != NULL) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, ": "); + } + fprintf(stderr, "%s\n", strerror(sverrno)); + exit(eval); +} + +void +err(int eval, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verr(eval, fmt, ap); + va_end(ap); +} + +void +errc(int eval, int code, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verrc(eval, code, fmt, ap); + va_end(ap); +} + +void +errx(int eval, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verrx(eval, fmt, ap); + va_end(ap); +} + +void +warn(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarn(fmt, ap); + va_end(ap); +} + +void +warnc(int code, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarnc(code, fmt, ap); + va_end(ap); +} + +void +warnx(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); +} +#endif /* !HAVE_ERR */ +#if !HAVE_GETPROGNAME +/* + * Copyright (c) 2016 Nicholas Marriott + * Copyright (c) 2017 Kristaps Dzonsons + * Copyright (c) 2020 Stephen Gregoratto + * + * 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 MIND, 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. + */ + +#include + +#include + +#if HAVE_GETEXECNAME +#include +const char * +getprogname(void) +{ + return getexecname(); +} +#elif HAVE_PROGRAM_INVOCATION_SHORT_NAME +const char * +getprogname(void) +{ + return (program_invocation_short_name); +} +#elif HAVE___PROGNAME +const char * +getprogname(void) +{ + extern char *__progname; + + return (__progname); +} +#else +#error No getprogname available. +#endif +#endif /* !HAVE_GETPROGNAME */ +#if !HAVE_SETRESGID +/* + * Copyright (c) 2004, 2005 Darren Tucker (dtucker at zip com au). + * + * 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. + */ + +#include +#include + +int +setresgid(gid_t rgid, gid_t egid, gid_t sgid) +{ + /* this is the only configuration tested */ + + if (rgid != egid || egid != sgid) + return -1; + + if (setregid(rgid, egid) == -1) + return -1; + + return 0; +} +#endif /* !HAVE_SETRESGID */ +#if !HAVE_SETRESUID +/* + * Copyright (c) 2004, 2005 Darren Tucker (dtucker at zip com au). + * + * 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. + */ + +#include + +#include +#include + +int +setresuid(uid_t ruid, uid_t euid, uid_t suid) +{ + uid_t ouid; + int ret = -1; + + /* Allow only the tested configuration. */ + + if (ruid != euid || euid != suid) { + errno = ENOSYS; + return -1; + } + ouid = getuid(); + + if ((ret = setreuid(euid, euid)) == -1) + return -1; + + /* + * When real, effective and saved uids are the same and we have + * changed uids, sanity check that we cannot restore the old uid. + */ + + if (ruid == euid && euid == suid && ouid != ruid && + setuid(ouid) != -1 && seteuid(ouid) != -1) { + errno = EINVAL; + return -1; + } + + /* + * Finally, check that the real and effective uids are what we + * expect. + */ + if (getuid() != ruid || geteuid() != euid) { + errno = EACCES; + return -1; + } + + return ret; +} +#endif /* !HAVE_SETRESUID */ +#if !HAVE_STRLCAT +/* + * Copyright (c) 1998 Todd C. Miller + * + * 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. + */ + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} +#endif /* !HAVE_STRLCAT */ +#if !HAVE_STRLCPY +/* + * Copyright (c) 1998 Todd C. Miller + * + * 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. + */ + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} +#endif /* !HAVE_STRLCPY */ +#if !HAVE_STRNDUP +/* $OpenBSD$ */ +/* + * Copyright (c) 2010 Todd C. Miller + * + * 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. + */ + +#include + +#include +#include +#include + +char * +strndup(const char *str, size_t maxlen) +{ + char *copy; + size_t len; + + len = strnlen(str, maxlen); + copy = malloc(len + 1); + if (copy != NULL) { + (void)memcpy(copy, str, len); + copy[len] = '\0'; + } + + return copy; +} +#endif /* !HAVE_STRNDUP */ +#if !HAVE_STRNLEN +/* $OpenBSD$ */ + +/* + * Copyright (c) 2010 Todd C. Miller + * + * 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. + */ + +#include +#include + +size_t +strnlen(const char *str, size_t maxlen) +{ + const char *cp; + + for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--) + ; + + return (size_t)(cp - str); +} +#endif /* !HAVE_STRNLEN */ +#if !HAVE_STRTONUM +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * 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. + */ + +#include +#include +#include + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + int error = 0; + char *ep; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) { + error = INVALID; + } else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} +#endif /* !HAVE_STRTONUM */ blob - /dev/null blob + 1653a88913601b12402476c448bf0bfcc70c69ef (mode 755) --- /dev/null +++ configure @@ -0,0 +1,815 @@ +#! /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.8" + +# +# 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 + +# try to be helpful +case "$1" in +--help|-h) + cat < 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 + +#---------------------------------------------------------------------- +# Initialize all variables here such that nothing can leak in from the +# environment except for CC and CFLAGS, which we might have passed in. +#---------------------------------------------------------------------- + +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" +LDADD= +LDADD_LIBEVENT= +LDADD_LIBEVENT2= +LDADD_LIB_SOCKET= +LDADD_STATIC= +CPPFLAGS= +LDFLAGS= +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. +#---------------------------------------------------------------------- + +while [ $# -gt 0 ]; do + key"${1%%=*}" + val="${1#*=}" + + if [ "$key" "-prefix" ]; then + key=PREFIX + if [ "$1" = "--prefix" ]; then + if ! shift 2>&1 >/dev/null; then + echo "$0: missing value for --prefix" >&2 + exit 1 + fi + val="$1" + fi + fi + + if [ "$1" = "$key" ]; then + echo "$0: invalid key-value: $1" >&2 + exit 1 + fi + + shift + + case "$key" in + LDADD) + LDADD="$val" ;; + LDADD_LIBEVENT) + LDADD_LIBEVENT="$val" ;; + LDADD_LIBEVENT2) + LDADD_LIBEVENT2="$val" ;; + LDADD_LIB_SOCKET) + LDADD_LIB_SOCKET="$val" ;; + LDFLAGS) + LDFLAGS="$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" ;; + PKG_CONFIG) + PKG_CONFIG="$val" ;; + *) + echo "$0: invalid key: $key" 1>&2 + exit 1 + esac +done + +test -z "${PKG_CONFIG}" && { + PKG_CONFIG="$(command -v pkg-config)" 2>/dev/null && { + echo "found pkg-config: $PKG_CONFIG" 1>&2 + echo "found pkg-config: $PKG_CONFIG" 1>&3 + } || { + PKG_CONFIG=false + echo "pkg-config not found: $PKG_CONFIG" 1>&2 + echo "pkg-config not found: $PKG_CONFIG" 1>&3 + } +} + + +#---------------------------------------------------------------------- +# 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_ENDIAN_H= +HAVE_ERR= +HAVE_GETDTABLECOUNT= +HAVE_GETEXECNAME= +HAVE_GETPROGNAME= +HAVE_OSBYTEORDER_H= +HAVE_PATH_MAX= +HAVE_PLEDGE= +HAVE_PROGRAM_INVOCATION_SHORT_NAME= +HAVE_SETRESGID= +HAVE_SETRESUID= +HAVE_SOCK_NONBLOCK= +HAVE_STRLCAT= +HAVE_STRLCPY= +HAVE_STRTONUM= +HAVE_SYS_BYTEORDER_H= +HAVE_SYS_ENDIAN_H= +HAVE_SYS_QUEUE= +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 + test -n "${6}" && ${PKG_CONFIG} "${6}" + if [ $? -eq 0 ]; then + echo "${1}: ${CC} failed with $? (retrying)" 1>&3 + pkgcfs="$($PKG_CONFIG --cflags "$6")" + pkglib="$($PKG_CONFIG --libs "$6")" + cat 1>&3 <&3 2>&3; then + echo "${1}: ${CC} succeeded" 1>&3 + extralib="(with ${pkgcfs} ${pkglib})" + 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 + else + echo "${1}: ${CC} failed with $?" 1>&3 + echo 1>&3 + return 1 + fi + fi + + if [ -n "${pkgcfs}" -o -n "${pkglib}" ] + then + CFLAGS="${CFLAGS} ${pkgcfs}" + eval "LDADD_${2}=\"${pkglib}\"" + elif [ -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, pkg-config name. + +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 endian_h ENDIAN_H || true +runtest err ERR || true +runtest getdtablecount GETDTABLECOUNT || true +runtest getexecname GETEXECNAME || true +runtest getprogname GETPROGNAME || true + +runtest libevent LIBEVENT "" "" "-levent" || \ +runtest libevent2 LIBEVENT2 "" "" "-levent_extra -levent_core" "libevent" || true + +runtest lib_socket LIB_SOCKET "" "" "-lsocket -lnsl" || 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 setresgid SETRESGID || true +runtest setresuid SETRESUID || true +runtest SOCK_NONBLOCK SOCK_NONBLOCK || true +runtest static STATIC "" "-static" || true +runtest strlcat STRLCAT || true +runtest strlcpy STRLCPY || true +runtest strtonum STRTONUM || true +runtest sys_byteorder_h SYS_BYTEORDER_H || true +runtest sys_endian_h SYS_ENDIAN_H || true +runtest sys_queue SYS_QUEUE || true +runtest WAIT_ANY WAIT_ANY || true +runtest __progname __PROGNAME || true + +if [ "${HAVE_LIBEVENT}" -eq 0 -a "${HAVE_LIBEVENT2:-0}" -eq 0 ]; then + echo "Fatal: missing libevent" 1>&2 + echo "Fatal: missing libevent" 1>&3 + exit 1 +fi + +#---------------------------------------------------------------------- +# 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__) +# 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_SETRESGID} -eq 0 -o \ + ${HAVE_SETRESUID} -eq 0 -o \ + ${HAVE_STRLCAT} -eq 0 -o \ + ${HAVE_STRLCPY} -eq 0 ] +then + echo "#include /* size_t, mode_t, dev_t */ " + echo +fi + +if [ ${HAVE_SYS_QUEUE} -eq 1 ] +then + echo "#include " + echo +fi + +if [ ${HAVE_ERR} -eq 1 ] +then + echo "#include /* err(3) */" + echo +fi + +if [ ${HAVE_LIBEVENT2:-0} -eq 1 ]; then + cat < +#include +#include +#include +#include +#include +#include +#include + +EOF +fi + +if [ ${HAVE_LIBEVENT} -eq 1 ]; then + cat < + +EOF +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 + + +cat << __HEREDOC__ +/* + * Results of configuration feature-testing. + */ +#define HAVE_ENDIAN_H ${HAVE_ENDIAN_H} +#define HAVE_ERR ${HAVE_ERR} +#define HAVE_GETDTABLECOUNT ${HAVE_GETDTABLECOUNT} +#define HAVE_GETEXECNAME ${HAVE_GETEXECNAME} +#define HAVE_GETPROGNAME ${HAVE_GETPROGNAME} +#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_SETRESGID ${HAVE_SETRESGID} +#define HAVE_SETRESUID ${HAVE_SETRESUID} +#define HAVE_SOCK_NONBLOCK ${HAVE_SOCK_NONBLOCK} +#define HAVE_STRLCAT ${HAVE_STRLCAT} +#define HAVE_STRLCPY ${HAVE_STRLCPY} +#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_QUEUE ${HAVE_SYS_QUEUE} +#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 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_GETDTABLECOUNT} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for getdtablecount(2). + */ +/* on linux could be implemented by looking in /proc/self/fd */ +#define getdtablecount() (0) + +__HEREDOC__ + +[ ${HAVE_GETPROGNAME} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for getprogname(3). + */ +extern const char *getprogname(void); + +__HEREDOC__ + +[ ${HAVE_PLEDGE} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for pledge(2). + */ +#define pledge(p, e) (0) + +__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_STRTONUM} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for strotnum(3). + */ +extern long long strtonum(const char *, long long, long long, const char **); + +__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__ + +[ ${HAVE_SYS_QUEUE} -eq 0 ] && \ + cat << __HEREDOC__ +#include "queue.h" + +__HEREDOC__ + +cat << __HEREDOC__ +#ifndef __dead +#define __dead __attribute__((noreturn)) +#endif + +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + +#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__ +CC = ${CC} +CFLAGS = ${CFLAGS} +CPPFLAGS = ${CPPFLAGS} +LDADD = ${LDADD} ${LDADD_LIB_SOCKET} ${LDADD_LIBEVENT} ${LDADD_LIBEVENT2} +LDADD_STATIC = ${LDADD_STATIC} +LDFLAGS = ${LDFLAGS} +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 blob - /dev/null blob + 48650541d70f49e1aa5b4615b80f71703309e8b0 (mode 644) --- /dev/null +++ configure.local.example @@ -0,0 +1,72 @@ +# +# Copyright (c) 2022 Omar Polo +# Copyright (c) 2014-2022 Ingo Schwarze +# +# 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. + +# For all settings documented in this file, there are reasonable +# defaults and/or the ./configure script attempts autodetection. +# Consequently, you only need to create a file ./configure.local +# and put any of these settings into it if ./configure autodetection +# fails or if you want to make different choices for other reasons. + +# If autodetection fails, please tell . + +# We recommend that you write ./configure.local from scratch and +# only put the lines there you need. This file contains examples. +# It is not intended as a template to be copied as a whole. + +# Some systems may want to set additional linker flags for all the +# binaries, for example for hardening options. + +LDFLAGS="-Wl,-z,relro" + +# It may be needed to change the flags for the individual libraries. + +LDADD_LIBEVENT2="-L/opt/lib/ -levent_extra -levent_core" +LDADD_LIB_VORBISFILE= + +# To disable the autoconfiguration via pkg-config set PKG_CONFIG to `false' + +PKG_CONFIG=false + +# It is possible to change the utility program used for installation +# and the modes files are installed with. The defaults are: + +INSTALL="install" +INSTALL_PROGRAM="${INSTALL} -m 0555" +INSTALL_LIB="${INSTALL} -m 0444" +INSTALL_MAN="${INSTALL} -m 0444" +INSTALL_DATA="${INSTALL} -m 0444" + +# In rare cases, it may be required to skip individual automatic tests. +# Each of the following variables can be set to 0 (test will not be run +# and will be regarded as failed) or 1 (test will not be run and will +# be regarded as successful). + +HAVE_ENDIAN_H=0 +HAVE_ERR=0 +HAVE_GETDTABLECOUNT=0 +HAVE_GETEXECNAME=0 +HAVE_GETPROGNAME=0 +HAVE_LIBEVENT=0 +HAVE_LIBEVENT2=0 +HAVE_PATH_MAX=0 +HAVE_PLEDGE=0 +HAVE_PROGRAM_INVOCATION_SHORT_NAME=0 +HAVE_STRLCAT=0 +HAVE_STRLCPY=0 +HAVE_STRTONUM=0 +HAVE_SYS_QUEUE=0 +HAVE_WAIT_ANY=0 +HAVE___PROGNAME=0 blob - /dev/null blob + 9cd9aad01fe0196eb6bb233493e4dabc0dc20625 (mode 644) --- /dev/null +++ queue.h @@ -0,0 +1,619 @@ +/* + * 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) blob - /dev/null blob + 8c32bd4333cf321d5d86152e5d1dfe69200df329 (mode 644) --- /dev/null +++ tests.c @@ -0,0 +1,370 @@ +#if TEST___PROGNAME +int +main(void) +{ + extern char *__progname; + + return !__progname; +} +#endif /* TEST___PROGNAME */ +#if TEST_ENDIAN_H +#ifdef __linux__ +# define _DEFAULT_SOURCE +#endif +#include + +int +main(void) +{ + return !htole32(23); +} +#endif /* TEST_ENDIAN_H */ +#if TEST_ERR +/* + * Copyright (c) 2015 Ingo Schwarze + * + * 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. + */ + +#include +#include + +int +main(void) +{ + warnx("%d. warnx", 1); + warnc(ENOENT, "%d. warn", ENOENT); + warn("%d. warn", 2); + err(0, "%d. err", 3); + errx(0, "%d. err", 3); + errc(0, ENOENT, "%d. err", 3); + /* NOTREACHED */ + return 1; +} +#endif /* TEST_ERR */ +#if TEST_GETDTABLECOUNT +#include + +int +main(void) +{ + return getdtablecount() == 0; +} +#endif /* TEST_GETDTABLECOUNT */ +#if TEST_GETEXECNAME +#include + +int +main(void) +{ + const char * progname; + + progname = getexecname(); + return progname == NULL; +} +#endif /* TEST_GETEXECNAME */ +#if TEST_GETPROGNAME +#include + +int +main(void) +{ + const char * progname; + + progname = getprogname(); + return progname == NULL; +} +#endif /* TEST_GETPROGNAME */ +#if TEST_LIBEVENT +#include + +int +main(void) +{ + struct event ev; + + event_set(&ev, 0, EV_READ, NULL, NULL); + event_add(&ev, NULL); + event_del(&ev); + return 0; +} +#endif /* TEST_LIBEVENT */ +#if TEST_LIBEVENT2 +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(void) +{ + struct event ev; + + event_set(&ev, 0, EV_READ, NULL, NULL); + event_add(&ev, NULL); + event_del(&ev); + return 0; +} +#endif /* TEST_LIBEVENT2 */ +#if TEST_LIB_SOCKET +#include + +int +main(void) +{ + int fds[2], c; + + c = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); + return c == -1; +} +#endif /* TEST_LIB_SOCKET */ +#if TEST_OSBYTEORDER_H +#include + +int +main(void) +{ + return !OSSwapHostToLittleInt32(23); +} +#endif /* TEST_OSBYTEORDER_H */ +#if TEST_PATH_MAX +/* + * POSIX allows PATH_MAX to not be defined, see + * http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html; + * the GNU Hurd is an example of a system not having it. + * + * Arguably, it would be better to test sysconf(_SC_PATH_MAX), + * but since the individual *.c files include "config.h" before + * , overriding an excessive value of PATH_MAX from + * "config.h" is impossible anyway, so for now, the simplest + * fix is to provide a value only on systems not having any. + * So far, we encountered no system defining PATH_MAX to an + * impractically large value, even though POSIX explicitly + * allows that. + * + * The real fix would be to replace all static buffers of size + * PATH_MAX by dynamically allocated buffers. But that is + * somewhat intrusive because it touches several files and + * because it requires changing struct mlink in mandocdb.c. + * So i'm postponing that for now. + */ + +#include +#include + +int +main(void) +{ + printf("PATH_MAX is defined to be %ld\n", (long)PATH_MAX); + return 0; +} +#endif /* TEST_PATH_MAX */ +#if TEST_PLEDGE +#include + +int +main(void) +{ + return !!pledge("stdio", NULL); +} +#endif /* TEST_PLEDGE */ +#if TEST_PROGRAM_INVOCATION_SHORT_NAME +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include + +int +main(void) +{ + + return !program_invocation_short_name; +} +#endif /* TEST_PROGRAM_INVOCATION_SHORT_NAME */ +#if TEST_SETRESGID +#define _GNU_SOURCE /* linux */ +#include +#include + +int +main(void) +{ + return setresgid(-1, -1, -1) == -1; +} +#endif /* TEST_SETRESGID */ +#if TEST_SETRESUID +#define _GNU_SOURCE /* linux */ +#include +#include + +int +main(void) +{ + return setresuid(-1, -1, -1) == -1; +} +#endif /* TEST_SETRESUID */ +#if TEST_SOCK_NONBLOCK +/* + * Linux doesn't (always?) have this. + */ + +#include + +int +main(void) +{ + int fd[2]; + socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK, 0, fd); + return 0; +} +#endif /* TEST_SOCK_NONBLOCK */ +#if TEST_STATIC +int +main(void) +{ + return 0; /* not meant to do anything */ +} +#endif /* TEST_STATIC */ +#if TEST_STRLCAT +#include + +int +main(void) +{ + char buf[3] = "a"; + return ! (strlcat(buf, "b", sizeof(buf)) == 2 && + buf[0] == 'a' && buf[1] == 'b' && buf[2] == '\0'); +} +#endif /* TEST_STRLCAT */ +#if TEST_STRLCPY +#include + +int +main(void) +{ + char buf[2] = ""; + return ! (strlcpy(buf, "a", sizeof(buf)) == 1 && + buf[0] == 'a' && buf[1] == '\0'); +} +#endif /* TEST_STRLCPY */ +#if TEST_STRTONUM +/* + * Copyright (c) 2015 Ingo Schwarze + * + * 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. + */ +#ifdef __NetBSD__ +# define _OPENBSD_SOURCE +#endif +#include + +int +main(void) +{ + const char *errstr; + + if (strtonum("1", 0, 2, &errstr) != 1) + return 1; + if (errstr != NULL) + return 2; + if (strtonum("1x", 0, 2, &errstr) != 0) + return 3; + if (errstr == NULL) + return 4; + if (strtonum("2", 0, 1, &errstr) != 0) + return 5; + if (errstr == NULL) + return 6; + if (strtonum("0", 1, 2, &errstr) != 0) + return 7; + if (errstr == NULL) + return 8; + return 0; +} +#endif /* TEST_STRTONUM */ +#if TEST_SYS_BYTEORDER_H +#include + +int +main(void) +{ + return !LE_32(23); +} +#endif /* TEST_SYS_BYTEORDER_H */ +#if TEST_SYS_ENDIAN_H +#include + +int +main(void) +{ + return !htole32(23); +} +#endif /* TEST_SYS_ENDIAN_H */ +#if TEST_SYS_QUEUE +#include +#include + +struct foo { + int bar; + TAILQ_ENTRY(foo) entries; +}; + +TAILQ_HEAD(fooq, foo); + +int +main(void) +{ + struct fooq foo_q, bar_q; + struct foo *p, *tmp; + int i = 0; + + TAILQ_INIT(&foo_q); + TAILQ_INIT(&bar_q); + + /* + * Use TAILQ_FOREACH_SAFE because some systems (e.g., Linux) + * have TAILQ_FOREACH but not the safe variant. + */ + + TAILQ_FOREACH_SAFE(p, &foo_q, entries, tmp) + p->bar = i++; + + /* Test for newer macros as well. */ + + TAILQ_CONCAT(&foo_q, &bar_q, entries); + return 0; +} +#endif /* TEST_SYS_QUEUE */ +#if TEST_WAIT_ANY +#include + +int +main(void) +{ + int st; + + return waitpid(WAIT_ANY, &st, WNOHANG) != -1; +} +#endif /* TEST_WAIT_ANY */