aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--Makefile19
-rw-r--r--compat/err.c84
-rw-r--r--compat/getprogname.c21
-rw-r--r--compat/strlcat.c54
-rw-r--r--compat/strlcpy.c49
-rw-r--r--compat/vasprintf.c46
-rwxr-xr-xconfigure328
-rw-r--r--gmid.h2
-rw-r--r--have/err.c26
-rw-r--r--have/getprogname.c23
-rw-r--r--have/libtls.c23
-rw-r--r--have/noop.c21
-rw-r--r--have/strlcat.c25
-rw-r--r--have/strlcpy.c25
-rw-r--r--have/vasprintf.c46
16 files changed, 786 insertions, 12 deletions
diff --git a/.gitignore b/.gitignore
index bcbdc5f..c77ea7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,9 @@ iri_test
docs
lex.yy.c
y.tab.*
+Makefile.local
+config.h
+config.h.old
+config.log
+config.log.old
+configure.local
diff --git a/Makefile b/Makefile
index 75ac470..7cb798d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,17 +1,11 @@
-CC = cc
-CFLAGS = -Wall -Wextra -g
-LDFLAGS = -ltls
-LEX = lex
-YACC = yacc
-
-PREFIX = /usr/local
+.PHONY: all static clean test install
-# /usr/local/lib on FreeBSD
-LIBDIR = /usr/lib/
+all: Makefile.local gmid TAGS
-.PHONY: all static clean test install
+Makefile.local: configure
+ ./configure
-all: gmid TAGS
+include Makefile.local
lex.yy.c: lex.l y.tab.c
${LEX} lex.l
@@ -20,7 +14,7 @@ y.tab.c: parse.y
${YACC} -b y -d parse.y
SRCS = gmid.c iri.c utf8.c ex.c server.c sandbox.c mime.c
-OBJS = ${SRCS:.c=.o} lex.yy.o y.tab.o
+OBJS = ${SRCS:.c=.o} lex.yy.o y.tab.o ${COMPAT}
gmid: ${OBJS}
${CC} ${OBJS} -o gmid ${LDFLAGS}
@@ -36,6 +30,7 @@ TAGS: ${SRCS}
clean:
rm -f *.o lex.yy.c y.tab.c y.tab.h y.output gmid iri_test
+ rm -f Makefile.local
iri_test: iri_test.o iri.o utf8.o
${CC} iri_test.o iri.o utf8.o -o iri_test ${LDFLAGS}
diff --git a/compat/err.c b/compat/err.c
new file mode 100644
index 0000000..840acd0
--- /dev/null
+++ b/compat/err.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * 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 <errno.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+/* cheat: if we don't have getprogname in stdlib, will link against
+ * compat/getprogname.c anyway. */
+const char *getprogname(void);
+
+static void vwarn_impl(const char*, va_list);
+static void vwarnx_impl(const char*, va_list);
+
+static void
+vwarn_impl(const char *fmt, va_list ap)
+{
+ fprintf(stderr, "%s: ", getprogname());
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ": %s\n", strerror(errno));
+}
+
+static void
+vwarnx_impl(const char *fmt, va_list ap)
+{
+ fprintf(stderr, "%s: ", getprogname());
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+}
+
+void
+err(int ret, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarn_impl(fmt, va);
+ va_end(ap, fmt);
+ exit(ret);
+}
+
+void
+errx(int ret, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarnx_impl(fmt, va);
+ va_end(ap, fmt);
+ exit(ret);
+}
+
+void
+warn(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarn_impl(fmt, va);
+ va_end(ap, fmt);
+}
+
+void
+warnx(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarnx_impl(fmt, va);
+ va_end(ap, fmt);
+}
diff --git a/compat/getprogname.c b/compat/getprogname.c
new file mode 100644
index 0000000..f162268
--- /dev/null
+++ b/compat/getprogname.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * 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.
+ */
+
+const char *
+getprogname(void)
+{
+ return "gmid";
+}
diff --git a/compat/strlcat.c b/compat/strlcat.c
new file mode 100644
index 0000000..2aa3f74
--- /dev/null
+++ b/compat/strlcat.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
+ *
+ * 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 "config.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left). At most dsize-1 characters
+ * will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+size_t
+strlcat(char *dst, const char *src, size_t dsize)
+{
+ const char *odst = dst;
+ const char *osrc = src;
+ size_t n = dsize;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end. */
+ while (n-- != 0 && *dst != '\0')
+ dst++;
+ dlen = dst - odst;
+ n = dsize - dlen;
+
+ if (n-- == 0)
+ return(dlen + strlen(src));
+ while (*src != '\0') {
+ if (n != 0) {
+ *dst++ = *src;
+ n--;
+ }
+ src++;
+ }
+ *dst = '\0';
+
+ return(dlen + (src - osrc)); /* count does not include NUL */
+}
diff --git a/compat/strlcpy.c b/compat/strlcpy.c
new file mode 100644
index 0000000..7edee76
--- /dev/null
+++ b/compat/strlcpy.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
+ *
+ * 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 "config.h"
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy string src to buffer dst of size dsize. At most dsize-1
+ * chars will be copied. Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t dsize)
+{
+ const char *osrc = src;
+ size_t nleft = dsize;
+
+ /* Copy as many bytes as will fit. */
+ if (nleft != 0) {
+ while (--nleft != 0) {
+ if ((*dst++ = *src++) == '\0')
+ break;
+ }
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src. */
+ if (nleft == 0) {
+ if (dsize != 0)
+ *dst = '\0'; /* NUL-terminate dst */
+ while (*src++)
+ ;
+ }
+
+ return(src - osrc - 1); /* count does not include NUL */
+}
diff --git a/compat/vasprintf.c b/compat/vasprintf.c
new file mode 100644
index 0000000..d76f3ef
--- /dev/null
+++ b/compat/vasprintf.c
@@ -0,0 +1,46 @@
+/* from mandoc, with tweaks */
+/*
+ * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * 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.
+ *
+ * This fallback implementation is not efficient:
+ * It does the formatting twice.
+ * Short of fiddling with the unknown internals of the system's
+ * printf(3) or completely reimplementing printf(3), i can't think
+ * of another portable solution.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+vasprintf(char **ret, const char *format, va_list ap)
+{
+ char buf[2];
+ va_list ap2;
+ int sz;
+
+ va_copy(ap2, ap);
+ sz = vsnprintf(buf, sizeof(buf), format, ap2);
+ va_end(ap2);
+
+ if (sz != -1 && (*ret = malloc(sz + 1)) != NULL) {
+ if (vsnprintf(*ret, sz + 1, format, ap) == sz)
+ return sz;
+ free(*ret);
+ }
+ *ret = NULL;
+ return -1;
+}
diff --git a/configure b/configure
new file mode 100755
index 0000000..328c7cf
--- /dev/null
+++ b/configure
@@ -0,0 +1,328 @@
+#!/bin/sh
+#
+# Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+#
+# 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.
+
+# adapted from mandoc configure and oconfigure, thanks schwarze@ and
+# kristaps@!
+
+set -e
+
+[ -w config.log ] && mv config.log config.log.old
+[ -w config.h ] && mv config.h config.h.old
+
+# Output file descriptor usage:
+# 1 (stdout): config.h, Makefile.local
+# 2 (stderr): original stderr, usually to the console
+# 3: config.log
+
+exec 3> config.log
+echo "file config.log: writing..."
+
+# --------
+# default settings: initialize all vars here
+
+CC=cc
+CFLAGS=
+LDFLAGS=-ltls
+YACC=yacc
+LEX=lex
+STATIC=
+
+HAVE_ERR=
+HAVE_GETPROGNAME=
+HAVE_LIBTLS=
+HAVE_STRLCAT=
+HAVE_STRLCPY=
+HAVE_VASPRINTF=
+
+NEED_GNU_SOURCE=0
+NEED_OPENBSD_SOURCE=0
+
+PREFIX="/usr/local"
+BINDIR=
+
+INSTALL="install"
+
+# try to auto detect CFLAGS and LDFLAGS
+which pkg-config 2>/dev/null 1>&2 && {
+ if ! got=`pkg-config --cflags libtls`; then
+ CFLAGS="$got"
+ fi
+
+ if ! got=`pkg-config --libs libtls`; then
+ LDFLAGS="$got"
+ fi
+}
+
+# auto detect lex/flex
+which ${LEX} 2>/dev/null 1>&2 || {
+ echo "${LEX} not found: trying flex" 1>&2
+ echo "${LEX} not found: trying flex" 1>&3
+ LEX=flex
+ which ${LEX} 2>/dev/null 1>&2 || {
+ echo "${LEX} not found: giving up" 1>&2
+ echo "${LEX} not found: giving up" 1>&3
+ exit 1
+ }
+}
+
+# auto detect yacc/bison
+which ${YACC} 2>/dev/null 1>&2 || {
+ echo "${YACC} not found: trying bison" 1>&2
+ echo "${YACC} not found: trying bison" 1>&3
+ YACC=bison
+ which ${YACC} 2>/dev/null 1>&2 || {
+ echo "${YACC} not found: giving up" 1>&2
+ echo "${YACC} not found: giving up" 1>&3
+ exit 1
+ }
+}
+
+# --------
+# allow certain variables to be overridden on the command line
+
+for keyvals in "$@"; do
+ key=`echo $keyvals | cut -s -d '=' -f1`
+ if [ -z "$key" ]; then
+ echo "$0: invalid key-value: $keyvals" 1>&2
+ exit 1
+ fi
+ vals=`echo $keyvals | cut -d '=' -f 2-`
+ case "$key" in
+ BINDIR) BINDIR="$val" ;;
+ CC) CC="$val" ;;
+ CFLAGS) CFLAGS="$val" ;;
+ DESTDIR) DESTDIR="$val" ;;
+ LDFLAGS) LDFLAGS="$val" ;;
+ LEX) LEX="$lex" ;;
+ PREFIX) PREFIX="$val" ;;
+ YACC) YACC="$val" ;;
+ *)
+ echo "$0: invalid key: $key" 1>&2
+ exit 1
+ esac
+done
+
+# --------
+# tests functions
+
+# Check whether this HAVE_ setting is manually overridden.
+# If yes, use the override, if no, do not decide anything yet.
+# Arguments: test file name, test var name, manual value
+ismanual() {
+ [ -z "${3}" ] && return 1
+ echo "tested ${1}: HAVE_${2}=${3} (manual)" 1>&2
+ echo "tested ${1}: HAVE_${2}=${3} (manual)" 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: test file name, test var name, additional CFLAGS
+singletest() {
+ n=${1}${3}
+ cat 1>&3 << __HEREDOC__
+testing ${n} ...
+${COMP} -o have/${1} have/${1}.c ${3} ${LDFLAGS}
+__HEREDOC__
+
+ if ${COMP} -o "have/${1}" "have/${1}.c" ${3} ${LDFLAGS} 1>&3 2>&3
+ then
+ echo "partial result of ${n}: ${CC} succeeded" 1>&3
+ else
+ echo "tested ${n}: no (compilation failed)" 1>&2
+ echo "result of ${n}: ${CC} failed with exit status $?" 1>&3
+ echo "result of compiling ${n}: no" 1>&3
+ echo 1>&3
+ return 1
+ fi
+
+ if ./have/${1} 1>&3 2>&3; then
+ echo "tested ${n}: yes" 1>&2
+ echo "result of running ${n}: yes" 1>&3
+ echo 1>&3
+ eval HAVE_${2}=1
+ [ "${3}" = "-D_GNU_SOURCE" ] && NEED_GNU_SOURCE=1
+ [ "${3}" = "-D_OPENBSD_SOURCE" ] && NEED_OPENBSD_SOURCE=1
+ [ "${3}" = "-lsocket" ] && LD_RECVMSG="-lsocket"
+ rm "have/${1}"
+ return 0
+ else
+ echo "tested ${n}: no (execution failed)" 1>&2
+ echo "result of ${n}: execution failed with exit status $?" 1>&3
+ echo "result of running ${n}: no" 1>&3
+ echo 1>&3
+ rm "have/${1}"
+ return 1
+ fi
+}
+
+# Run a complete autoconfiguration test, including the check for
+# a manual override and disabling the feature on failure.
+# Arguments: test file name, test var name, additional CFLAGS
+# The final argument can optionally be repeated a second time.
+runtest() {
+ eval _manual=\${HAVE_${2}}
+ ismanual "${1}" "${2}" "${_manual}" && return 0
+ singletest "${1}" "${2}" "${3}" && return 0
+ [ -n "${4}" ] && singletest "${1}" "${2}" "${4}" && return 0
+ eval HAVE_${2}=0
+ return 1
+}
+
+# --------
+# compiler options
+
+DEFCFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings -Wno-unused-parameter"
+
+if [ -n "${CFLAGS}" ]; then
+ COMP="${CC} ${CFLAGS} -Wno-unused -Werror"
+else
+ COMP="${CC} ${CDEFCFLAGS} -Wno-unused -Werror"
+fi
+echo -n "testing ${CC} -W: " 1>&2
+echo -n "testing ${CC} -W: " 1>&3
+runtest noop WFLAG || true
+
+if [ -n "${CFLAGS}" ]; then
+ echo "CFLAGS specified manually:" 1>&3
+elif [ ${HAVE_WFLAG} -eq 0 ]; then
+ CFLAGS="-g"
+else
+ CFLAGS="${DEFCFLAGS}"
+fi
+echo "selected CFLAGS=\"${CFLAGS}\"" 1>&2
+echo "selected CFLAGS=\"${CFLAGS}\"" 1>&3
+echo 1>&3
+
+COMP="${CC} ${CFLAGS}"
+[ ${HAVE_WFLAG} -eq 0 ] || COMP="${COMP} -Wno-unused -Werror"
+
+if [ -n "${STATIC}" ]; then
+ echo "selected STATIC=\"${STATIC}\" (manual)" 1>&2
+ echo "selected STATIC=\"${STATIC}\" (manual)" 1>&3
+ echo 1>&3
+else
+ runtest noop STATIC -static || true
+ [ ${HAVE_STATIC} -eq 0 ] || STATIC="-static"
+ echo "selected STATIC=\"${STATIC}\"" 1>&2
+ echo "selected STATIC=\"${STATIC}\"" 1>&3
+ echo 1>&3
+fi
+
+# --------
+# tests for config.h
+
+runtest err ERR || true
+runtest libtls LIBTLS || true
+runtest strlcat STRLCAT || true
+runtest strlcpy STRLCPY || true
+runtest vasprintf VASPRINTF "" -D_GNU_SOURCE || true
+
+if [ ${HAVE_LIBTLS} -eq 0 ]; then
+ echo "FATAL: libtls not found" 1>&2
+ echo "FATAL: libtls not found" 1>&3
+ exit 1
+fi
+
+# --------
+# write config.h
+
+exec > config.h
+
+cat <<__HEREDOC__
+#ifdef __cplusplus
+#error "Do not use C++."
+#endif
+
+__HEREDOC__
+
+[ ${NEED_GNU_SOURCE} -eq 0 ] || echo "#define _GNU_SOURCE"
+[ ${NEED_OPENBSD_SOURCE} -eq 0 ] || echo "#define _OPENBSD_SOURCE"
+
+[ ${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 ] \
+ && echo "#include <sys/types.h>"
+[ ${HAVE_VASPRINTF} -eq 0 ] && echo "#include <stdarg.h>"
+
+cat <<__HEREDOC__
+
+#define HAVE_ERR ${HAVE_ERR}
+#define HAVE_GETPROGNAME ${HAVE_GETPROGNAME}
+#define HAVE_STRLCAT ${HAVE_STRLCAT}
+#define HAVE_STRLCPY ${HAVE_STRLCPY}
+#define HAVE_VASPRINTF ${HAVE_VASPRINTF}
+
+__HEREDOC__
+
+if [ ${HAVE_ERR} -eq 0 ]; then
+ echo "extern void err(int, const char*, ...);"
+ echo "extern void errx(int, const char*, ...);"
+ echo "extern void warn(const char*, ...);"
+ echo "extern void warnx(const char*, ...);"
+ COMPAT="${COMPAT} compat/err.o"
+fi
+
+if [ ${HAVE_STRLCAT} -eq 0 ]; then
+ echo "extern size_t strlcat(char*, const char*, size_t);"
+ COMPAT="${COMPAT} compat/strlcat.o"
+fi
+if [ ${HAVE_STRLCPY} -eq 0 ]; then
+ echo "extern size_t strlcpy(char*, const char*, size_t);"
+ COMPAT="${COMPAT} compat/strlcpy.o"
+fi
+if [ ${HAVE_VASPRINTF} -eq 0 ]; then
+ echo "extern int vasprintf(char**, const char*, va_list);"
+ COMPAT="${COMPAT} compat/vasprintf.o"
+fi
+echo "file config.h: written" 1>&2
+echo "file config.h: written" 1>&3
+
+# --------
+# tests for Makefile.local
+
+exec > Makefile.local
+
+[ -z "${BINDIR}" ] && BINDIR="${PREFIX}/bin"
+[ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man"
+
+[ -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}
+LDFLAGS = ${LDFLAGS}
+YACC = ${YACC}
+LEX = ${LEX}
+COMPAT = ${COMPAT}
+STATIC = ${STATIC}
+PREFIX = ${PREFIX}
+BINDIR = ${BINDIR}
+INCLUDEDIR = ${INCLUDEDIR}
+INSTALL = ${INSTALL}
+INSTALL_PROGRAM = ${INSTALL_PROGRAM}
+INSTALL_LIB = ${INSTALL_LIB}
+INSTALL_MAN = ${INSTALL_MAN}
+INSTALL_DATA = ${INSTALL_DATA}
+__HEREDOC__
+
+echo "file Makefile.local: written" 1>&2
+echo "file Makefile.local: written" 1>&3
+
+exit 0
diff --git a/gmid.h b/gmid.h
index cd38c51..a6b8781 100644
--- a/gmid.h
+++ b/gmid.h
@@ -28,6 +28,8 @@
#include <tls.h>
#include <unistd.h>
+#include "config.h"
+
#ifndef INFTIM
# define INFTIM -1
#endif
diff --git a/have/err.c b/have/err.c
new file mode 100644
index 0000000..93eb816
--- /dev/null
+++ b/have/err.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * 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 <err.h>
+
+int
+main(void)
+{
+ warnx("%d. warnx", 1);
+ warn("%d. warn", 2);
+ err(0, "%d. err", 3);
+ return 1;
+}
diff --git a/have/getprogname.c b/have/getprogname.c
new file mode 100644
index 0000000..57c0e2b
--- /dev/null
+++ b/have/getprogname.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * 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 <stdlib.h>
+
+int
+main(void)
+{
+ return getprogname() == NULL;
+}
diff --git a/have/libtls.c b/have/libtls.c
new file mode 100644
index 0000000..42f83e4
--- /dev/null
+++ b/have/libtls.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * 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 <tls.h>
+
+int
+main(void)
+{
+ return tls_init() != 0;
+}
diff --git a/have/noop.c b/have/noop.c
new file mode 100644
index 0000000..928d54f
--- /dev/null
+++ b/have/noop.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * 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.
+ */
+
+int
+main(void)
+{
+ return 0;
+}
diff --git a/have/strlcat.c b/have/strlcat.c
new file mode 100644
index 0000000..0a005c5
--- /dev/null
+++ b/have/strlcat.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * 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 <string.h>
+
+int
+main(void)
+{
+ char buf[3] = "a";
+ return ! (strlcat(buf, "b", sizeof(buf)) == 2 &&
+ buf[0] == 'a' && buf[1] == 'b' && buf[2] == '\0');
+}
diff --git a/have/strlcpy.c b/have/strlcpy.c
new file mode 100644
index 0000000..d178935
--- /dev/null
+++ b/have/strlcpy.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * 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 <string.h>
+
+int
+main(void)
+{
+ char buf[2] = "";
+ return ! (strlcpy(buf, "a", sizeof(buf)) == 1 &&
+ buf[0] == 'a' && buf[1] == '\0');
+}
diff --git a/have/vasprintf.c b/have/vasprintf.c
new file mode 100644
index 0000000..2d1ac0b
--- /dev/null
+++ b/have/vasprintf.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * 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 <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+static int testfn(char **, const char*, ...);
+
+static int
+testfn(char **ret, const char *fmt, ...)
+{
+ va_list ap;
+ int irc;
+
+ va_start(ap, fmt);
+ irc = vasprintf(ret, fmt, ap);
+ va_end(ap);
+
+ return irc;
+}
+
+int
+main(void)
+{
+ char *ret;
+
+ if (testfn(&ret, "%s.", "Text") != 5)
+ return 1;
+ if (strcmp(ret, "Text."))
+ return 2;
+ return 0;
+}