1#!/bin/sh
2# Try and be like autotools configure, but without autotools
3
4echo "configure args: $*"
5exec 3>config.log
6
7# Ensure that we do not inherit these from env
8HOOKSET=false
9INET=
10INET6=
11ARC4RANDOM=
12CLOSEFROM=
13GETLINE=
14STRLCPY=
15UDEV=
16OS=
17BUILD=
18HOST=
19HOSTCC=
20TARGET=
21DEBUG=
22FORK=
23STATIC=
24INCLUDEDIR=
25DEVS=
26EMBEDDED=
27POLL=
28DBUS=
29
30for x do
31	opt=${x%%=*}
32	var=${x#*=}
33	case "$opt" in
34	--os|OS) OS=$var;;
35	--debug) DEBUG=$var;;
36	--disable-debug) DEBUG=no;;
37	--enable-debug) DEBUG=yes;;
38	--fork) FORK=$var;;
39	--disable-fork) FORK=no;;
40	--enable-fork) FORK=yes;;
41	--disable-static) STATIC=no;;
42	--enable-static) STATIC=yes;;
43	--disable-ipv4) INET=no;;
44	--enable-ipv4) INET=yes;;
45	--disable-ipv6) INET6=no;;
46	--enable-ipv6) INET6=yes;;
47	--disable-embedded) EMBEDDED=no;;
48	--enable-embedded) EMBEDDED=yes;;
49	--enable-dbus) DBUS=yes;;
50	--disable-dbus) DBUS=no;;
51	--prefix) PREFIX=$var;;
52	--sysconfdir) SYSCONFDIR=$var;;
53	--bindir|--sbindir) SBINDIR=$var;;
54	--libexecdir) LIBEXECDIR=$var;;
55	--statedir|--localstatedir) STATEDIR=$var;;
56	--dbdir) DBDIR=$var;;
57	--rundir) RUNDIR=$var;;
58	--mandir) MANDIR=$var;;
59	--with-ccopts|CFLAGS) CFLAGS=$var;;
60	CC) CC=$var;;
61	CPPFLAGS) CPPFLAGS=$var;;
62	--with-hook) HOOKSCRIPTS="$HOOKSCRIPTS${HOOKSCRIPTS:+ }$var";;
63	--with-hooks|HOOKSCRIPTS) HOOKSCRIPTS=$var; HOOKSET=true;;
64	--build) BUILD=$var;;
65	--host) HOST=$var; HOSTCC=$var-;;
66	--target) TARGET=$var;;
67	--libdir) LIBDIR=$var;;
68	--without-arc4random) ARC4RANDOM=no;;
69	--without-closefrom) CLOSEFROM=no;;
70	--without-getline) GETLINE=no;;
71	--without-strlcpy) STRLCPY=no;;
72        --without-posix_spawn) POSIX_SPAWN=no;;
73	--without-md5) MD5=no;;
74	--without-sha2) SHA2=no;;
75	--without-sha256) SHA2=no;;
76	--without-dev) DEV=no;;
77	--without-udev) UDEV=no;;
78	--with-poll) POLL="$var";;
79	--serviceexists) SERVICEEXISTS=$var;;
80	--servicecmd) SERVICECMD=$var;;
81	--servicestatus) SERVICESTATUS=$var;;
82	--includedir) eval INCLUDEDIR="$INCLUDEDIR${INCLUDEDIR:+ }$var";;
83	--datadir|--infodir) ;; # ignore autotools
84	--disable-maintainer-mode|--disable-dependency-tracking) ;;
85	--disable-silent-rules) ;;
86	-V|--version)
87		v=$(sed -ne 's/.*VERSION[[:space:]]*"\([^"]*\).*/\1/p' defs.h);
88		c=$(sed -ne 's/^.*copyright\[\] = "\([^"]*\).*/\1/p' dhcpcd.c);
89		echo "dhcpcd-$v $c";
90		exit 0;;
91	-h|--help) cat <<EOF
92\`configure' configures this package to adapt to many kinds of systems.
93
94Usage: configure [OPTION]... [VAR=VALUE]...
95
96To assign environment variables (e.g., CC, CFLAGS...), specify them as
97VAR=VALUE.  See below for descriptions of some of the useful variables.
98
99Defaults for the options are specified in brackets.
100
101Configuration:
102  -h, --help              display this help and exit
103      --help=short        display options specific to this package
104  -V, --version           display version information and exit
105
106Installation directories:
107  --prefix=PREFIX         install architecture-independent files in PREFIX [/]
108
109By default, \`make install' will install all the files in \'/sbin',
110\`/libexec', etc. You can specify
111an installation prefix other than \`/' using \`--prefix',
112for instance \`--prefix=$HOME'.
113
114For better control, use the options below.
115
116Fine tuning of the installation directories:
117  --bindir=DIR            user executables [PREFIX/bin]
118  --sbindir=DIR           system admin executables [PREFIX/sbin]
119  --libexecdir=DIR        program executables [PREFIX/libexec]
120  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
121  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
122  --libdir=DIR            object code libraries [PREFIX/lib]
123  --includedir=DIR        C header files [PREFIX/include]
124  --mandir=DIR            man documentation [PREFIX/man]
125
126System types:
127  --build=BUILD           configure for building on BUILD [guessed]
128  --host=HOST       build programs to run on HOST [BUILD]
129  --target=TARGET   configure for building compilers for TARGET [HOST]
130
131Optional Features:
132  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
133  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
134
135Some influential environment variables:
136  CC          C compiler command
137  CFLAGS      C compiler flags
138  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
139              nonstandard directory <lib dir>
140  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
141              headers in a nonstandard directory <include dir>
142  CPP         C preprocessor
143
144Use these variables to override the choices made by \`configure' or to help
145it to find libraries and programs with nonstandard names/locations.
146EOF
147exit 0
148;;
149	*) echo "$0: WARNING: unknown option $opt" >&2;;
150	esac
151done
152
153: ${SED:=sed}
154: ${GREP:=grep}
155: ${WC:=wc}
156
157: ${FORK:=yes}
158: ${SYSCONFDIR:=$PREFIX/etc}
159: ${SBINDIR:=$PREFIX/sbin}
160: ${LIBDIR:=$PREFIX/lib}
161: ${LIBEXECDIR:=$PREFIX/libexec}
162: ${STATEDIR:=/var}
163: ${DBDIR:=$STATEDIR/db}
164: ${RUNDIR:=$STATEDIR/run}
165: ${MANDIR:=${PREFIX:-/usr}/share/man}
166
167eval SYSCONFDIR="$SYSCONFDIR"
168eval LIBDIR="$LIBDIR"
169eval LIBEXECDIR="$LIBEXECDIR"
170eval STATEDIR="$STATEDIR"
171eval DBDIR="$DBDIR"
172eval RUNDIR="$RUNDIR"
173eval MANDIR="$MANDIR"
174
175_which()
176{
177	x="$(which "$1" 2>/dev/null)"
178	if [ -n "$x" ]; then
179		echo "$x"
180		return 0
181	fi
182	for x in /sbin/"$1" /usr/sbin/"$1" \
183		/usr/pkg/sbin/"$1" /usr/local/sbin/"$1"
184	do
185		if [ -e "$x" ]; then
186			echo "$x"
187			return 0
188		fi
189	done
190	return 1
191}
192
193CONFIG_H=config.h
194CONFIG_MK=config.mk
195
196if [ -z "$BUILD" ]; then
197	# autoconf target triplet: cpu-vendor-os
198	BUILD=$(uname -m)-unknown-$(uname -s | tr '[:upper:]' '[:lower:]')
199fi
200: ${HOST:=$BUILD}
201
202if [ -z "$OS" ]; then
203	echo "Deriving operating system from ... $HOST"
204	# Derive OS from cpu-vendor-[kernel-]os
205	CPU=${HOST%%-*}
206	REST=${HOST#*-}
207	if [ "$CPU" != "$REST" ]; then
208		VENDOR=${REST%%-*}
209		REST=${REST#*-}
210		if [ "$VENDOR" != "$REST" ]; then
211			# Use kernel if given, otherwise os
212			OS=${REST%%-*}
213		else
214			# 2 tupple
215			OS=$VENDOR
216			VENDOR=
217		fi
218	fi
219
220        # Work with cpu-kernel-os, ie Debian
221	case "$VENDOR" in
222	linux*|kfreebsd*) OS=$VENDOR; VENDOR= ;;
223	esac
224	# Special case
225	case "$OS" in
226	gnu*) OS=hurd;; # No HURD support as yet
227	esac
228fi
229
230echo "Configuring dhcpcd for ... $OS"
231rm -f $CONFIG_H $CONFIG_MK
232echo "# $OS" >$CONFIG_MK
233echo "/* $OS */" >$CONFIG_H
234
235for x in SYSCONFDIR SBINDIR LIBDIR LIBEXECDIR DBDIR RUNDIR; do
236	eval v=\$$x
237	# Make files look nice for import
238	l=$((10 - ${#x}))
239	unset t
240	[ $l -gt 3 ] && t="	"
241	echo "$x=$t	$v" >>$CONFIG_MK
242	unset t
243	[ $l -gt 2 ] && t="	"
244	echo "#define $x$t	\"$v\"" >>$CONFIG_H
245done
246echo "LIBDIR=		$LIBDIR" >>$CONFIG_MK
247echo "MANDIR=		$MANDIR" >>$CONFIG_MK
248
249# Always obey CC.
250if [ -n "$CC" ]; then
251	HOSTCC=
252else
253	CC=cc
254	_COMPILERS="cc clang gcc pcc icc"
255fi
256# Only look for a cross compiler if --host and --build are not the same
257if [ -n "$HOSTCC" -a "$BUILD" != "$HOST" ]; then
258	for _CC in $_COMPILERS; do
259		_CC=$(_which "$HOSTCC$_CC")
260		if [ -x "$_CC" ]; then
261			CC=$_CC
262			break
263		fi
264	done
265fi
266if ! type "$CC" >/dev/null 2>&1; then
267	for _CC in $_COMPILERS; do
268		_CC=$(_which "$_CC")
269		if [ -x "$_CC" ]; then
270			CC=$_CC
271			break
272		fi
273	done
274fi
275
276# Set to blank, then append user config
277# We do this so our SED call to append to XCC remains portable
278if [ -n "$CFLAGS" ]; then
279	echo "CFLAGS=" >>$CONFIG_MK
280	echo "CFLAGS+=	$CFLAGS" >>$CONFIG_MK
281fi
282if [ -n "$CPPFLAGS" ]; then
283	echo "CPPFLAGS=" >>$CONFIG_MK
284	echo "CPPFLAGS+=	$CPPFLAGS" >>$CONFIG_MK
285fi
286if [ -n "$LDFLAGS" ]; then
287	echo "LDFLAGS=" >>$CONFIG_MK
288	echo "LDFLAGS+=	$LDFLAGS" >>$CONFIG_MK
289fi
290
291# NetBSD: Even if we build for $PREFIX, the clueless user might move us to /
292LDELF=/libexec/ld.elf_so
293if [ -e "$LDELF" ]; then
294	echo "Linking against $LDELF"
295	echo "LDFLAGS+=	-Wl,-dynamic-linker=$LDELF" >>$CONFIG_MK
296	echo "LDFLAGS+=	-Wl,-rpath=${LIBDIR}" >>$CONFIG_MK
297fi
298
299if [ -z "$PREFIX" -o "$PREFIX" = / ]; then
300	ALLOW_USR_LIBS=false
301else
302	ALLOW_USR_LIBS=true
303fi
304case "$OS" in
305linux*|sunos*) ;;
306*)
307	if ! [ -x "$LDELF" -o -x /libexec/ld-elf.so.[0-9]* ] && \
308	    [ -z "$PREFIX" -o "$PREFIX" = "/" ]
309	then
310		echo "Forcing a static build for $OS and \$PREFIX of /"
311		STATIC=yes
312		ALLOW_USR_LIBS=true
313	fi
314	;;
315esac
316if [ "$STATIC" = yes ]; then
317	echo "LDFLAGS+=	-static" >>$CONFIG_MK
318fi
319for x in $INCLUDEDIR; do
320	echo "CPPFLAGS+=	-I$x" >>$CONFIG_MK
321done
322
323if [ -z "$DEBUG" -a -f .fslckout ]; then
324	printf "Found fossil checkout ... "
325	DEBUG=yes
326fi
327if [ -n "$DEBUG" -a "$DEBUG" != no -a "$DEBUG" != false ]; then
328	echo "Adding debugging CFLAGS"
329	cat <<EOF >>$CONFIG_MK
330CFLAGS+=	-g -Wall -Wextra
331CFLAGS+=	-Wmissing-prototypes -Wmissing-declarations
332CFLAGS+=	-Wmissing-format-attribute -Wnested-externs
333CFLAGS+=	-Winline -Wcast-align -Wcast-qual -Wpointer-arith
334CFLAGS+=	-Wreturn-type -Wswitch -Wshadow
335CFLAGS+=	-Wcast-qual -Wwrite-strings
336CFLAGS+=	-Wconversion
337CFLAGS+=	-Wformat=2
338CFLAGS+=	-Wpointer-sign -Wmissing-noreturn
339EOF
340	case "$OS" in
341	mirbsd*|openbsd*);; # OpenBSD has many redundant decs in system headers
342	*)		echo "CFLAGS+=	-Wredundant-decls" >>$CONFIG_MK;;
343	esac
344
345	case "$OS" in
346	sunos*);;
347	*)		echo "CFLAGS+=	-Wstrict-overflow" >>$CONFIG_MK;;
348	esac
349fi
350
351if [ -z "$EMBEDDED" -o "$EMBEDDED" = yes ]; then
352	echo "dhcpcd-definitions.conf will be embedded in dhcpcd itself"
353	echo "DHCPCD_SRCS+=	dhcpcd-embedded.c" >>$CONFIG_MK
354else
355	echo "dhcpcd-definitions.conf will be installed to $LIBEXECDIR"
356	echo "CFLAGS+= -DEMBEDDED_CONFIG=\\\"$LIBEXECDIR/dhcpcd-definitions.conf\\\"" >>$CONFIG_MK
357	echo "EMBEDDEDINSTALL=	_embeddedinstall" >>$CONFIG_MK
358fi
359
360if [ -n "$FORK" -a "$FORK" != yes -a "$FORK" != true ]; then
361	echo "There is no fork"
362	echo "CPPFLAGS+=	-DTHERE_IS_NO_FORK" >>$CONFIG_MK
363fi
364
365case "$OS" in
366freebsd*|kfreebsd*)
367	echo "CPPFLAGS+=	-D_GNU_SOURCE" >>$CONFIG_MK
368	echo "DHCPCD_SRCS+=	if-bsd.c" >>$CONFIG_MK
369	;;
370linux*)
371	echo "CPPFLAGS+=	-D_GNU_SOURCE" >>$CONFIG_MK
372	# Large File Support, should be fine for 32-bit systems.
373	# But if this is the case, why is it not set by default?
374	echo "CPPFLAGS+=	-D_FILE_OFFSET_BITS=64" >>$CONFIG_MK
375	echo "CPPFLAGS+=	-D_LARGEFILE_SOURCE" >>$CONFIG_MK
376	echo "CPPFLAGS+=	-D_LARGEFILE64_SOURCE" >>$CONFIG_MK
377	echo "DHCPCD_SRCS+=	if-linux.c" >>$CONFIG_MK
378	# for RTM_NEWADDR and friends
379	echo "#include		<asm/types.h> /* fix broken headers */" >>$CONFIG_H
380	echo "#include		<linux/rtnetlink.h>" >>$CONFIG_H
381	;;
382qnx*)
383	echo "CPPFLAGS+=	-D__EXT" >>$CONFIG_MK
384	echo "DHCPCD_SRCS+=	if-bsd.c" >>$CONFIG_MK
385	;;
386sunos*)
387	echo "WARNING!!! Solaris support is at early development stage!" >&2
388	echo "so don't expect it to work just yet, patches welcome" >&2
389	echo "CPPFLAGS+=	-D_XPG4_2 -D__EXTENSIONS__ -DBSD_COMP" \
390	    >>$CONFIG_MK
391	echo "DHCPCD_SRCS+=	if-sun.c" >>$CONFIG_MK
392
393	# IPv6 won't work, but it will at least compile.
394	echo "CPPFLAGS+=	-DIN6_IFF_DETACHED=0" >>$CONFIG_MK
395	echo "CPPFLAGS+=	-DIN6_IFF_TENTATIVE=0" >>$CONFIG_MK
396	echo "CPPFLAGS+=	-DIN6_IFF_DUPLICATED=0" >>$CONFIG_MK
397	;;
398*)
399	echo "DHCPCD_SRCS+=	if-bsd.c" >>$CONFIG_MK
400	;;
401esac
402
403if [ -z "$INET" -o "$INET" = yes ]; then
404	echo "CPPFLAGS+=	-DINET" >>$CONFIG_MK
405	echo "DHCPCD_SRCS+=	arp.c dhcp.c ipv4.c ipv4ll.c" >>$CONFIG_MK
406fi
407if [ -z "$INET6" -o "$INET6" = yes ]; then
408	echo "CPPFLAGS+=	-DINET6" >>$CONFIG_MK
409	echo "DHCPCD_SRCS+=	ipv6.c ipv6nd.c dhcp6.c" >>$CONFIG_MK
410fi
411
412if [ "$DBUS" = yes ]; then
413	echo "DBUS_SUPPORT= yes" >>$CONFIG_MK
414	echo "DBUSINSTALL=  _dbusinstall" >>$CONFIG_MK
415	echo "CPPFLAGS+=    -DPASSIVE_MODE" >>$CONFIG_MK
416	echo "DHCPCD_SRCS+= dbus/dbus-dict.c dbus/rpc-dbus.c" >>$CONFIG_MK
417else
418	echo "DHCPCD_SRCS+= rpc-stub.c" >>$CONFIG_MK
419fi
420
421if [ -z  "$HOOKSCRIPTS" ]; then
422	echo "DHCPCD_SRCS+= script-stub.c" >>$CONFIG_MK
423else
424	echo "HOOK_SUPPORT= yes" >>$CONFIG_MK
425	echo "SCRIPTSINSTALL=  _scriptsinstall" >>$CONFIG_MK
426	echo "DHCPCD_SRCS+= script.c" >>$CONFIG_MK
427fi
428
429echo "Using compiler .. $CC"
430# Add CPPFLAGS and CFLAGS to CC for testing features
431XCC="$CC `$SED -n -e 's/CPPFLAGS+=*\(.*\)/\1/p' $CONFIG_MK`"
432XCC="$XCC `$SED -n -e 's/CFLAGS+=*\(.*\)/\1/p' $CONFIG_MK`"
433
434# Now test we can use the compiler with our CFLAGS
435cat <<EOF >_test.c
436int main(void) {
437	return 0;
438}
439EOF
440_CC=false
441if $XCC _test.c -o _test >/dev/null 2>&3; then
442	[ -x _test ] && _CC=true
443fi
444rm -f _test.c _test
445if ! $_CC; then
446	echo "$CC does not create executables"
447	exit 1
448fi
449[ "$CC" != cc ] && echo "CC=	$CC" >>$CONFIG_MK
450$CC --version | $SED -e '1!d'
451
452if [ "$OS" = linux ]; then
453	printf "Testing for nl80211 ... "
454	cat <<EOF >_nl80211.c
455#include <linux/nl80211.h>
456int main(void) {
457	return 0;
458}
459EOF
460	if $XCC _nl80211.c -o _nl80211 2>&3; then
461		echo "yes"
462		echo "#define HAVE_NL80211_H" >>$CONFIG_H
463	else
464		echo "no"
465	fi
466	rm -f _nl80211.c _nl80211
467
468	# Even though we have nl80211, we only use it as a fallback
469	# because it's currently possible to configure a kernel
470	# where the SSID associated to won't be reported by nl80211
471	# but will be via WEXT.
472	echo "DHCPCD_SRCS+=	if-linux-wext.c" >>$CONFIG_MK
473fi
474
475abort=false
476# We require the libc to support non standard functions, like getifaddrs
477printf "Testing for getifaddrs ... "
478cat <<EOF >_getifaddrs.c
479#include <sys/types.h>
480#include <ifaddrs.h>
481int main(void) {
482	struct ifaddrs *ifap;
483	return getifaddrs(&ifap);
484}
485EOF
486if $XCC _getifaddrs.c -o _getifaddrs 2>&3; then
487	echo "yes"
488elif $XCC _getifaddrs.c -o _getifaddrs -lsocket 2>&3; then
489	echo "yes (-lsocket)"
490	echo "LDADD+=		-lsocket" >>$CONFIG_MK
491else
492	echo "no"
493	echo "libc support for getifaddrs is required - aborting" >&2
494	abort=true
495fi
496rm -f _getifaddrs.c _getifaddrs
497$abort && exit 1
498
499printf "Testing for clock_gettime ... "
500cat <<EOF >_clock_gettime.c
501#include <time.h>
502int main(void) {
503	struct timespec ts;
504	return clock_gettime(CLOCK_MONOTONIC, &ts);
505}
506EOF
507if $XCC _clock_gettime.c -o _clock_gettime 2>&3; then
508	echo "yes"
509elif $XCC _clock_gettime.c -lrt -o _clock_gettime 2>&3; then
510	echo "yes (-lrt)"
511	echo "LDADD+=		-lrt" >>$CONFIG_MK
512else
513	echo "no"
514	echo "libc support for clock_getttime is required - aborting" >&2
515	abort=true
516fi
517rm -f _clock_gettime.c _clock_gettime
518$abort && exit 1
519
520printf "Testing for inet_ntoa ... "
521cat <<EOF >_inet_ntoa.c
522#include <netinet/in.h>
523#include <arpa/inet.h>
524int main(void) {
525	struct in_addr in;
526	inet_ntoa(in);
527	return 0;
528}
529EOF
530if $XCC _inet_ntoa.c -o _inet_ntoa 2>&3; then
531	echo "yes"
532elif $XCC _inet_ntoa.c -lnsl -o _inet_ntoa 2>&3; then
533	echo "yes (-lnsl)"
534	echo "LDADD+=		-lnsl" >>$CONFIG_MK
535elif $XCC _inet_ntoa.c -lsocket -o _inet_ntoa 2>&3; then
536	echo "yes (-lsocket)"
537	echo "LDADD+=		-lsocket" >>$CONFIG_MK	
538else
539	echo "no"
540	echo "libc support for inet_ntoa is required - aborting" >&2
541	abort=true
542fi
543rm -f _inet_ntoa.c _inet_ntoa
544$abort && exit 1
545
546if [ -z "$ARC4RANDOM" ]; then
547	printf "Testing for arc4random ... "
548	cat <<EOF >_arc4random.c
549#include <stdlib.h>
550int main(void) {
551	arc4random();
552	return 0;
553}
554EOF
555	if $XCC _arc4random.c -o _arc4random 2>&3; then
556		ARC4RANDOM=yes
557	else
558		ARC4RANDOM=no
559	fi
560	echo "$ARC4RANDOM"
561	rm -f _arc4random.c _arc4random
562fi
563if [ "$ARC4RANDOM" = no ]; then
564	echo "COMPAT_SRCS+=	compat/arc4random.c" >>$CONFIG_MK
565	echo "#include		\"compat/arc4random.h\"" >>$CONFIG_H
566fi
567
568if [ -z "$ARC4RANDOM_UNIFORM" ]; then
569	printf "Testing for arc4random_uniform ... "
570	cat <<EOF >_arc4random_uniform.c
571#include <stdlib.h>
572int main(void) {
573	arc4random_uniform(100);
574	return 0;
575}
576EOF
577	if $XCC _arc4random_uniform.c -o _arc4random_uniform 2>&3; then
578		ARC4RANDOM_UNIFORM=yes
579	else
580		ARC4RANDOM_UNIFORM=no
581	fi
582	echo "$ARC4RANDOM"
583	rm -f _arc4random_uniform.c _arc4random_uniform
584fi
585if [ "$ARC4RANDOM_UNIFORM" = no ]; then
586	echo "COMPAT_SRCS+=	compat/arc4random_uniform.c" >>$CONFIG_MK
587	echo "#include		\"compat/arc4random_uniform.h\"" >>$CONFIG_H
588fi
589
590if [ -z "$CLOSEFROM" ]; then
591	printf "Testing for closefrom ... "
592	cat <<EOF >_closefrom.c
593#include <unistd.h>
594int main(void) {
595	closefrom(3);
596	return 0;
597}
598EOF
599	if $XCC _closefrom.c -o _closefrom 2>&3; then
600		CLOSEFROM=yes
601	else
602		CLOSEFROM=no
603	fi
604	echo "$CLOSEFROM"
605	rm -f _closefrom.c _closefrom
606fi
607if [ "$CLOSEFROM" = no ]; then
608	echo "COMPAT_SRCS+=	compat/closefrom.c" >>$CONFIG_MK
609	echo "#include		\"compat/closefrom.h\"" >>$CONFIG_H
610fi
611
612if [ -z "$GETLINE" ]; then
613	printf "Testing for getline ... "
614	cat <<EOF >_getline.c
615#include <stdio.h>
616int main(void) {
617	char *buf = NULL;
618	size_t n = 0;
619	getline(&buf, &n, stdin);
620	return 0;
621}
622EOF
623	if $XCC _getline.c -o _getline 2>&3; then
624		GETLINE=yes
625	else
626		GETLINE=no
627	fi
628	echo "$GETLINE"
629	rm -f _getline.c _getline
630fi
631if [ "$GETLINE" = no ]; then
632	echo "COMPAT_SRCS+=	compat/getline.c" >>$CONFIG_MK
633	echo "#include		\"compat/getline.h\"" >>$CONFIG_H
634fi
635
636if [ -z "$STRLCPY" ]; then
637	printf "Testing for strlcpy ... "
638	cat <<EOF >_strlcpy.c
639#include <string.h>
640int main(void) {
641	const char s1[] = "foo";
642	char s2[10];
643	strlcpy(s2, s1, sizeof(s2));
644	return 0;
645}
646EOF
647	if $XCC _strlcpy.c -o _strlcpy 2>&3; then
648		STRLCPY=yes
649	else
650		STRLCPY=no
651	fi
652	echo "$STRLCPY"
653	rm -f _strlcpy.c _strlcpy
654fi
655if [ "$STRLCPY" = no ]; then
656	echo "COMPAT_SRCS+=	compat/strlcpy.c" >>$CONFIG_MK
657	echo "#include		\"compat/strlcpy.h\"" >>$CONFIG_H
658fi
659
660if [ -z "$STRTOI" ]; then
661	printf "Testing for strtoi ... "
662	cat <<EOF >_strtoi.c
663#include <stdlib.h>
664#include <limits.h>
665#include <inttypes.h>
666int main(void) {
667	int e;
668	return strtoi("1234", NULL, 0, 0, INT32_MAX, &e);
669}
670EOF
671	if $XCC _strtoi.c -o _strtoi 2>&3; then
672		STRTOI=yes
673	else
674		STRTOI=no
675	fi
676	echo "$STRTOI"
677	rm -f _strtoi.c _strtoi
678fi
679if [ "$STRTOI" = no ]; then
680	echo "COMPAT_SRCS+=	compat/strtoi.c" >>$CONFIG_MK
681	echo "#include		\"compat/strtoi.h\"" >>$CONFIG_H
682fi
683
684if [ -z "$DPRINTF" ]; then
685	printf "Testing for dprintf ... "
686	cat <<EOF >_dprintf.c
687#include <stdio.h>
688int main(void) {
689	return dprintf(0, "%d", 0);
690}
691EOF
692	if $XCC _dprintf.c -o _dprintf 2>&3; then
693		DPRINTF=yes
694	else
695		DPRINTF=no
696	fi
697	echo "$DPRINTF"
698	rm -f _dprintf.c _dprintf
699fi
700if [ "$DPRINTF" = no ]; then
701	echo "COMPAT_SRCS+=	compat/dprintf.c" >>$CONFIG_MK
702	echo "#include		\"compat/dprintf.h\"" >>$CONFIG_H
703fi
704
705if [ -z "$TAILQ_FOREACH_SAFE" ]; then
706	printf "Testing for TAILQ_FOREACH_SAFE ... "
707	cat <<EOF >_queue.c
708#include <sys/queue.h>
709int main(void) {
710#ifndef TAILQ_FOREACH_SAFE
711#error TAILQ_FOREACH_SAFE
712#endif
713	return 0;
714}
715EOF
716	if $XCC _queue.c -o _queue 2>&3; then
717		TAILQ_FOREACH_SAFE=yes
718		TAILQ_FOREACH=yes
719	else
720		TAILQ_FOREACH_SAFE=no
721	fi
722	echo "$TAILQ_FOREACH_SAFE"
723	rm -f _queue.c _queue
724fi
725
726if [ -z "$TAILQ_CONCAT" ]; then
727	printf "Testing for TAILQ_CONCAT ..."
728	cat <<EOF >_queue.c
729#include <sys/queue.h>
730int main(void) {
731#ifndef TAILQ_CONCAT
732#error TAILQ_CONCAT
733#endif
734	return 0;
735}
736EOF
737	if $XCC _queue.c -o _queue 2>&3; then
738		TAILQ_CONCAT=yes
739		TAILQ_FOREACH=yes
740	else
741		TAILQ_CONCAT=no
742	fi
743	echo "$TAILQ_CONCAT"
744	rm -f _queue.c _queue
745fi
746
747if [ -z "$TAILQ_FOREACH" ]; then
748	printf "Testing for TAILQ_FOREACH ... "
749	cat <<EOF >_queue.c
750#include <sys/queue.h>
751int main(void) {
752#ifndef TAILQ_FOREACH
753#error TAILQ_FOREACH
754#endif
755	return 0;
756}
757EOF
758	if $XCC _queue.c -o _queue 2>&3; then
759		TAILQ_FOREACH=yes
760	else
761		TAILQ_FOREACH=no
762	fi
763	echo "$TAILQ_FOREACH"
764	rm -f _queue.c _queue
765fi
766
767if [ "$TAILQ_FOREACH_SAFE" = no -o "$TAILQ_CONCAT" = no ]; then
768	# If we don't include sys/queue.h then clang analyser finds
769	# too many false positives.
770	# See http://llvm.org/bugs/show_bug.cgi?id=18222
771	# Strictly speaking this isn't needed, but I like it to help
772	# catch any nasties.
773	if [ "$TAILQ_FOREACH" = yes ]; then
774		echo "#include		<sys/queue.h>">>$CONFIG_H
775	fi
776	echo "#include		\"compat/queue.h\"">>$CONFIG_H
777else
778	echo "#include		<sys/queue.h>" >>$CONFIG_H
779fi
780
781if [ -z "$POSIX_SPAWN" ]; then
782	printf "Testing for posix_spawn ... "
783	cat <<EOF >_posix_spawn.c
784#include <spawn.h>
785#include <stdlib.h>
786
787#ifdef __OpenBSD__
788#  include <sys/param.h>
789#  if OpenBSD<201505
790#    error posix_spawn was fixed in OpenBSD-5.7
791#  endif
792#endif
793
794int main(void) {
795	posix_spawn(NULL, NULL, NULL, NULL, NULL, NULL);
796	return 0;
797}
798EOF
799	if $XCC _posix_spawn.c -o _posix_spawn 2>&3; then
800		POSIX_SPAWN=yes
801	else
802		POSIX_SPAWN=no
803	fi
804	echo "$POSIX_SPAWN"
805	rm -f _posix_spawn.c _posix_spawn
806fi
807if [ "$POSIX_SPAWN" = no ]; then
808	echo "COMPAT_SRCS+=	compat/posix_spawn.c" >>$CONFIG_MK
809else
810	echo "#define HAVE_SPAWN_H" >>$CONFIG_H
811fi
812
813if [ -z "$POLL" ]; then
814	printf "Testing for kqueue1 ... "
815	cat <<EOF >_kqueue.c
816#include <sys/types.h>
817#include <sys/event.h>
818int main(void) {
819	return kqueue1(0);
820}
821EOF
822	if $XCC _kqueue.c -o _kqueue 2>&3; then
823		POLL=kqueue1
824 		echo "yes"
825 	else
826 		echo "no"
827 	fi
828	rm -f _kqueue.c _kqueue
829fi
830if [ -z "$POLL" ]; then
831	printf "Testing for kqueue ... "
832	cat <<EOF >_kqueue.c
833#include <sys/types.h>
834#include <sys/event.h>
835int main(void) {
836	return kqueue();
837}
838EOF
839	if $XCC _kqueue.c -o _kqueue 2>&3; then
840		POLL=kqueue
841 		echo "yes"
842 	else
843 		echo "no"
844 	fi
845	rm -f _kqueue.c _kqueue
846fi
847if [ -z "$POLL" ]; then
848	printf "Testing for epoll ... "
849	cat <<EOF >_epoll.c
850#ifdef __linux__
851#include <linux/version.h>
852#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
853#error kernel has buggy epoll_wait timeout
854#endif
855#endif
856
857#include <sys/epoll.h>
858#include <unistd.h>
859int main(void) {
860	epoll_create1(EPOLL_CLOEXEC);
861	epoll_pwait(-1, NULL, 0, 0, NULL);
862	return 0;
863}
864EOF
865	if $XCC _epoll.c -o _epoll 2>&3; then
866		POLL=epoll
867		echo "#define HAVE_EPOLL" >>$CONFIG_MK
868		echo "yes"
869	else
870		echo "no"
871	fi
872	rm -f _epoll.c _epoll
873fi
874if [ -z "$POLL" ]; then
875	printf "Testing for ppoll ... "
876	cat <<EOF >_ppoll.c
877#include <poll.h>
878#include <stdlib.h>
879int main(void) {
880	ppoll(NULL, 0, NULL, NULL);
881	return 0;
882}
883EOF
884	if $XCC _ppoll.c -o _ppoll 2>&3; then
885		POLL=ppoll
886 		echo "yes"
887 	else
888 		echo "no"
889 	fi
890	rm -f _ppoll.c _ppoll
891fi
892if [ -z "$POLL" ]; then
893	printf "Testing for pselect ... "
894	cat <<EOF >_pselect.c
895#include <sys/select.h>
896#include <stdlib.h>
897int main(void) {
898	pselect(0, NULL, NULL, NULL, NULL, NULL);
899	return 0;
900}
901EOF
902	if $XCC _pselect.c -o _pselect 2>&3; then
903		POLL=pselect
904		echo "yes"
905	else
906		echo "no"
907	fi
908	rm -f _pselect.c _pselect
909fi
910case "$POLL" in
911kqueue1)
912	echo "#define HAVE_KQUEUE" >>$CONFIG_H
913	echo "#define HAVE_KQUEUE1" >>$CONFIG_H
914	;;
915kqueue)
916	echo "#define HAVE_KQUEUE" >>$CONFIG_H
917	;;
918epoll)
919	echo "#define HAVE_EPOLL" >>$CONFIG_H
920	;;
921ppoll)
922	echo "#define pollts		ppoll" >>$CONFIG_H
923	;;
924pselect)
925	echo "COMPAT_SRCS+=	compat/pselect.c" >>$CONFIG_MK
926	echo "#include		\"compat/pollts.h\"" >>$CONFIG_H
927	;;
928*)
929	echo "COMPAT_SRCS+=	compat/pollts.c" >>$CONFIG_MK
930	echo "#include		\"compat/pollts.h\"" >>$CONFIG_H
931	;;
932esac
933
934if [ -z "$BE64ENC" ]; then
935	printf "Testing for be64enc ... "
936	cat <<EOF >_be64enc.c
937#include <sys/endian.h>
938#include <stdlib.h>
939int main(void) {
940	be64enc(NULL, 0);
941}
942EOF
943	if $XCC _be64enc.c -o _be64enc 2>&3; then
944		BE64ENC=yes
945	else
946		BE64ENC=no
947	fi
948	echo "$BE64ENC"
949	rm -f _be64enc.c _be64enc
950fi
951if [ "$BE64ENC" = no ]; then
952	echo "#include		\"compat/endian.h\"" >>$CONFIG_H
953fi
954
955if [ -z "$MD5" ]; then
956	MD5_LIB=
957	printf "Testing for MD5Init ... "
958	cat <<EOF >_md5.c
959#include <sys/types.h>
960#include <md5.h>
961#include <stdlib.h>
962int main(void) {
963	MD5_CTX context;
964	MD5Init(&context);
965	return 0;
966}
967EOF
968	# We only want to link to libmd if it exists in /lib
969	if $ALLOW_USR_LIBS; then
970		set -- /
971	else
972		set -- $(ls /lib/libmd.so.* 2>/dev/null)
973	fi
974	if $XCC _md5.c -o _md5 2>&3; then
975		MD5=yes
976	elif [ -e "$1" ] && $XCC _md5.c -lmd -o _md5 2>&3; then
977		MD5="yes (-lmd)"
978		MD5_LIB=-lmd
979	else
980		MD5=no
981	fi
982	echo "$MD5"
983	rm -f _md5.c _md5
984fi
985if [ "$MD5" = no ]; then
986	echo "MD5_SRC=	crypt/md5.c" >>$CONFIG_MK
987else
988	echo "MD5_SRC=" >>$CONFIG_MK
989	echo "#define HAVE_MD5_H" >>$CONFIG_H
990	[ -n "$MD5_LIB" ] && echo "LDADD+=		$MD5_LIB" >>$CONFIG_MK
991fi
992
993if [ -z "$SHA2_H" -a -z "$SHA2" -o "$SHA2" != no ]; then
994	printf "Testing for sha2.h ... "
995	if [ -e /usr/include/sha2.h ]; then
996		SHA2_H=sha2.h
997	elif [ -e /usr/include/sha256.h ]; then
998		SHA2_H=sha256.h
999	fi
1000	if [ -n "$SHA2_H" ]; then
1001		echo "$SHA2_H"
1002	else
1003		echo "no"
1004	fi
1005fi
1006
1007if [ -z "$SHA2" ]; then
1008	SHA2_LIB=
1009	SHA2_RENAMED=
1010	printf "Testing for SHA256_Init ... "
1011	cat <<EOF >_sha256.c
1012#include <sys/types.h>
1013EOF
1014	[ -n "$SHA2_H" ] && echo "#include <$SHA2_H>">>_sha256.c
1015	cat <<EOF >>_sha256.c
1016#include <stdlib.h>
1017int main(void) {
1018	SHA256_CTX context;
1019	SHA256_Init(&context);
1020	return 0;
1021}
1022EOF
1023	# We only want to link to libmd if it exists in /lib
1024	if $ALLOW_USR_LIBS; then
1025		set -- /
1026	else
1027		set -- $(ls /lib/libmd.so.* 2>/dev/null)
1028	fi
1029	if $XCC _sha256.c -o _sha256 2>&3; then
1030		SHA2=yes
1031	elif [ -e "$1" ] && $XCC _sha256.c -lmd -o _sha256 2>&3; then
1032		SHA2="yes (-lmd)"
1033		SHA2_LIB=-lmd
1034	else
1035		SHA2=no
1036	fi
1037	echo "$SHA2"
1038	rm -f _sha256.c _sha256
1039	if [ "$SHA2" = no ]; then
1040		# Did OpenBSD really change this? grrrr
1041		printf "Testing for SHA256Init ... "
1042		cat <<EOF >_sha256.c
1043#include <sys/types.h>
1044EOF
1045		[ -n "$SHA2_H" ] && echo "#include <$SHA2_H>">>_sha256.c
1046		cat <<EOF >>_sha256.c
1047#include <stdlib.h>
1048int main(void) {
1049	SHA2_CTX context;
1050	SHA256Init(&context);
1051	return 0;
1052}
1053EOF
1054		# We only want to link to libmd if it exists in /lib
1055		if $ALLOW_USR_LIBS; then
1056			set -- /
1057		else
1058			set -- $(ls /lib/libmd.so.* 2>/dev/null)
1059		fi
1060		if $XCC	_sha256.c -o _sha256 2>&3; then
1061			SHA2=yes
1062			SHA2_RENAMED=yes
1063		elif [ -e "$1" ] && $XCC _sha256.c -lmd -o _sha256 2>&3
1064		then
1065			SHA2="yes (-lmd)"
1066			SHA2_LIB=-lmd
1067			SHA2_RENAMED=yes
1068		else
1069			SHA2=no
1070		fi
1071		echo "$SHA2"
1072		rm -f _sha256.c _sha256
1073	fi
1074fi
1075if [ "$SHA2" = no ]; then
1076	echo "SHA256_SRC=	crypt/sha256.c" >>$CONFIG_MK
1077else
1078	echo "SHA256_SRC=" >>$CONFIG_MK
1079	echo "#define SHA2_H		<$SHA2_H>" >>$CONFIG_H
1080	if [ "$SHA2_RENAMED" = yes ]; then
1081		echo "#define SHA256_CTX	SHA2_CTX" >>$CONFIG_H
1082		echo "#define SHA256_Init	SHA256Init" >>$CONFIG_H
1083		echo "#define SHA256_Update	SHA256Update" >>$CONFIG_H
1084		echo "#define SHA256_Final	SHA256Final" >>$CONFIG_H
1085	fi
1086	[ -n "$SHA2_LIB" ] && echo "LDADD+=		$SHA2_LIB" >>$CONFIG_MK
1087fi
1088
1089if [ "$DEV" != no -a "$UDEV" != no ]; then
1090	printf "Checking for libudev ... "
1091	if type pkg-config >/dev/null 2>&1; then
1092		LIBUDEV_CFLAGS=$(pkg-config --cflags libudev 2>&3)
1093		LIBUDEV_LIBS=$(pkg-config --libs libudev 2>&3)
1094	fi
1095fi
1096if [ "$DEV" != no -a "$UDEV" != no -a -n "$LIBUDEV_LIBS" ]; then
1097	echo "yes"
1098	[ -z "$DEV" ] && DEV=yes
1099	echo "DEV_PLUGINS+=	udev" >>$CONFIG_MK
1100	if [ -n "$LIBUDEV_CFLAGS" ]; then
1101		echo "LIBUDEV_CFLAGS=		$LIBUDEV_CFLAGS" >>$CONFIG_MK
1102	fi
1103	echo "LIBUDEV_LIBS=	$LIBUDEV_LIBS" >>$CONFIG_MK
1104
1105	printf "Checking udev_monitor_filter_add_match_subsystem_devtype ... "
1106	cat <<EOF >_udev.c
1107#include <libudev.h>
1108#include <stdlib.h>
1109int main(void) {
1110	udev_monitor_filter_add_match_subsystem_devtype(NULL, NULL, NULL);
1111	return 0;
1112}
1113EOF
1114	if $XCC $LIBUDEV_CFLAGS _udev.c -o _udev $LIBUDEV_LIBS 2>&3
1115	then
1116		echo "yes"
1117	else
1118		echo "LIBUDEV_CPPFLAGS+=	-DLIBUDEV_NOFILTER" >>$CONFIG_MK
1119		echo "no"
1120	fi
1121	rm -f _udev.c _udev
1122
1123	printf "Checking udev_device_get_is_initialized ... "
1124	cat <<EOF >_udev.c
1125#include <libudev.h>
1126#include <stdlib.h>
1127int main(void) {
1128	udev_device_get_is_initialized(NULL);
1129	return 0;
1130}
1131EOF
1132	if $XCC $LIBUDEV_CFLAGS _udev.c -o _udev $LIBUDEV_LIBS 2>&3
1133	then
1134		echo "yes"
1135	else
1136		echo "LIBUDEV_CPPFLAGS+=	-DLIBUDEV_NOINIT" >>$CONFIG_MK
1137		echo "no"
1138	fi
1139	rm -f _udev.c _udev
1140elif [ "$DEV" != no -a "$UDEV" != no ]; then
1141	echo "no"
1142fi
1143
1144if [ "$DEV" = yes ]; then
1145	echo "DHCPCD_SRCS+=	dev.c" >>$CONFIG_MK
1146	echo "CPPFLAGS+=	-DPLUGIN_DEV" >>$CONFIG_MK
1147	echo "MKDIRS+=	dev" >>$CONFIG_MK
1148
1149	printf "Testing for dlopen ... "
1150	cat <<EOF >_dlopen.c
1151#include <dlfcn.h>
1152#include <stdlib.h>
1153int main(void) {
1154	dlopen(NULL, 0);
1155	return 0;
1156}
1157EOF
1158	if $XCC _dlopen.c -o _dlopen 2>&3; then
1159		echo "yes"
1160	elif $XCC _dlopen.c -ldl -o _dlopen 2>&3; then
1161		echo "yes (-ldl)"
1162		echo "LDADD+=		-ldl" >>$CONFIG_MK
1163	else
1164		echo "no"
1165		echo "libc for dlopen is required - aborting"
1166	fi
1167	rm -f _dlopen.c _dlopen
1168	$abort && exit 1
1169fi
1170
1171# Transform for a make file
1172SERVICEEXISTS=$(echo "$SERVICEEXISTS" | $SED \
1173	-e 's:\\:\\\\:g' \
1174	-e 's:\&:\\\&:g' \
1175	-e 's:\$:\\\\\$\$:g' \
1176)
1177echo "SERVICEEXISTS=	$SERVICEEXISTS" >>config.mk
1178SERVICECMD=$(echo "$SERVICECMD" | $SED \
1179	-e 's:\\:\\\\:g' \
1180	-e 's:\&:\\\&:g' \
1181	-e 's:\$:\\\\\$\$:g' \
1182)
1183echo "SERVICECMD=	$SERVICECMD" >>config.mk
1184SERVICESTATUS=$(echo "$SERVICESTATUS" | $SED \
1185	-e 's:\\:\\\\:g' \
1186	-e 's:\&:\\\&:g' \
1187	-e 's:\$:\\\\\$\$:g' \
1188)
1189echo "SERVICESTATUS=	$SERVICESTATUS" >>config.mk
1190
1191HOOKS=
1192if ! $HOOKSET; then
1193	printf "Checking for ntpd ... "
1194	NTPD=$(_which ntpd)
1195	if [ -n "$NTPD" ]; then
1196		echo "$NTPD (50-ntp.conf)"
1197		HOOKS="$HOOKS${HOOKS:+ }50-ntp.conf"
1198	else
1199		echo "not found"
1200	fi
1201
1202	printf "Checking for ypbind ... "
1203	YPBIND=$(_which ypbind)
1204	if [ -n "$YPBIND" ]; then
1205		YPHOOK="50-ypbind"
1206		if strings "$YPBIND" | $GREP -q yp\\.conf; then
1207			YPHOOK="50-yp.conf"
1208			YPOS="Linux"
1209		elif strings "$YPBIND" | $GREP -q \\.ypservers; then
1210			YPOS="NetBSD"
1211			echo "YPDOMAIN_DIR=	/var/yp" >>$CONFIG_MK
1212			echo "YPDOMAIN_SUFFIX=.ypservers" >>$CONFIG_MK
1213		elif strings "$YPBIND" | $GREP -q /etc/yp; then
1214			YPOS="OpenBSD"
1215			echo "YPDOMAIN_DIR=	/etc/yp" >>$CONFIG_MK
1216			echo "YPDOMAIN_SUFFIX=" >>$CONFIG_MK
1217		else
1218			YPOS="FreeBSD"
1219			echo "YPDOMAIN_DIR=" >>$CONFIG_MK
1220			echo "YPDOMAIN_SUFFIX=" >>$CONFIG_MK
1221		fi
1222		echo "$YPBIND ($YPHOOK${YPOS:+ }$YPOS)"
1223		HOOKS="$HOOKS${HOOKS:+ }$YPHOOK"
1224	else
1225		echo "not found"
1226	fi
1227fi
1228
1229if cd dhcpcd-hooks; then
1230	for x in $HOOKSCRIPTS; do
1231		printf "Finding hook $x ... "
1232		for h in [0-9][0-9]"-$x" \
1233		    [0-9][0-9]"-$x.sh" \
1234		    [0-9][0-9]"-$x.conf"
1235		do
1236			[ -e "$h" ] && break
1237		done
1238		if [ ! -e "$h" ]; then
1239			echo "no"
1240		else
1241			echo "$h"
1242			case " $HOOKS " in
1243			*" $h "*)	;;
1244			*)		HOOKS="$HOOKS${HOOKS:+ }$h";;
1245			esac
1246		fi
1247	done
1248	cd ..
1249fi
1250echo "HOOKSCRIPTS=	$HOOKS" >>$CONFIG_MK
1251
1252echo
1253echo "   SYSCONFDIR =		$SYSCONFDIR"
1254echo "   SBINDIR =		$SBINDIR"
1255echo "   LIBDIR =		$LIBDIR"
1256echo "   LIBEXECDIR =		$LIBEXECDIR"
1257echo "   DBDIR =		$DBDIR"
1258echo "   RUNDIR =		$RUNDIR"
1259echo "   MANDIR =		$MANDIR"
1260echo "   HOOKSCRIPTS =	$HOOKS"
1261echo
1262
1263rm -f dhcpcd tests/test
1264