mk-conf.sh, mk-mk.in: use variables for *all* utilities
[s-mailx.git] / mk-conf.sh
blob845168c7c81d1429a6e5bd1c7706ee40a98d0f06
1 #!/bin/sh -
2 #@ Please see `INSTALL' and `conf.rc' instead.
4 LC_ALL=C
5 export LC_ALL
7 # Predefined CONFIG= urations take precedence over anything else
8 if [ -n "${CONFIG}" ]; then
9 case ${CONFIG} in
10 MINIMAL)
11 WANT_SOCKETS=0
12 WANT_IDNA=0
13 WANT_READLINE=0 WANT_EDITLINE=0 WANT_NCL=0
14 WANT_REGEX=0
15 WANT_SPAM=0
16 WANT_DOCSTRINGS=0
17 WANT_QUOTE_FOLD=0
19 MEDIUM)
20 WANT_SOCKETS=0
21 WANT_IDNA=0
22 WANT_READLINE=0 WANT_EDITLINE=0
23 WANT_REGEX=0
24 WANT_SPAM=0
25 WANT_QUOTE_FOLD=0
27 NETSEND)
28 WANT_IMAP=0
29 WANT_POP3=0
30 WANT_READLINE=0 WANT_EDITLINE=0
31 WANT_REGEX=0
32 WANT_SPAM=0
33 WANT_QUOTE_FOLD=0
36 echo >&2 "Unknown CONFIG= setting: ${CONFIG}"
37 echo >&2 'Possible values: MINIMAL, MEDIUM, NETSEND'
38 exit 1
39 esac
42 # Inter-relationships
43 option_update() {
44 if nwantfeat SOCKETS; then
45 WANT_IPV6=0 WANT_SSL=0
46 WANT_IMAP=0 WANT_GSSAPI=0 WANT_POP3=0 WANT_SMTP=0
48 if nwantfeat IMAP && nwantfeat POP3 && nwantfeat SMTP; then
49 WANT_SOCKETS=0 WANT_IPV6=0 WANT_SSL=0
51 if nwantfeat IMAP; then
52 WANT_GSSAPI=0
54 # If we don't need MD5 except for producing boundary and message-id strings,
55 # leave it off, plain old srand(3) should be enough for that purpose.
56 if nwantfeat SOCKETS; then
57 WANT_MD5=0
59 if wantfeat DEBUG; then
60 WANT_NOALLOCA=1
64 # Check out compiler ($CC) and -flags ($CFLAGS)
65 compiler_flags() {
66 i=`uname -s`
67 _CFLAGS=
69 # $CC is overwritten when empty or a default "cc", even without WANT_AUTOCC
70 if [ -z "${CC}" ] || [ "${CC}" = cc ]; then
71 _CFLAGS=
72 if { CC="`command -v clang`"; }; then
74 elif { CC="`command -v gcc`"; }; then
76 elif { CC="`command -v c89`"; }; then
77 [ "${i}" = UnixWare ] && _CFLAGS='-v -O'
78 elif { CC="`command -v c99`"; }; then
80 else
81 echo >&2 'ERROR'
82 echo >&2 ' I cannot find a compiler!'
83 echo >&2 ' Neither of clang(1), gcc(1), c89(1) and c99(1).'
84 echo >&2 ' Please set the CC environment variable, maybe CFLAGS also.'
85 exit 1
88 export CC
90 ccver=`${CC} --version 2>/dev/null`
91 stackprot=no
92 if { i=$ccver; echo "${i}"; } | ${grep} -q -i -e gcc -e clang; then
93 #if echo "${i}" | ${grep} -q -i -e gcc -e 'clang version 1'; then
94 stackprot=yes
95 _CFLAGS='-std=c89 -O2'
96 _CFLAGS="${_CFLAGS} -Wall -Wextra -pedantic"
97 _CFLAGS="${_CFLAGS} -fno-unwind-tables -fno-asynchronous-unwind-tables"
98 _CFLAGS="${_CFLAGS} -fstrict-aliasing"
99 _CFLAGS="${_CFLAGS} -Wbad-function-cast -Wcast-align -Wcast-qual"
100 _CFLAGS="${_CFLAGS} -Winit-self -Wshadow -Wunused -Wwrite-strings"
101 if { i=$ccver; echo "${i}"; } | ${grep} -q -e 'clang version 1'; then
103 else
104 _CFLAGS="${_CFLAGS} -fstrict-overflow -Wstrict-overflow=5"
105 if wantfeat AMALGAMATION && nwantfeat DEBUG; then
106 _CFLAGS="${_CFLAGS} -Wno-unused-function"
108 if { i=$ccver; echo "${i}"; } | ${grep} -q -i -e clang; then
109 _CFLAGS="${_CFLAGS} -Wno-unused-result" # TODO handle the right way
112 _CFLAGS="${_CFLAGS} -Wno-long-long" # ISO C89 has no 'long long'...
113 # elif { i=$ccver; echo "${i}"; } | ${grep} -q -i -e clang; then
114 # stackprot=yes
115 # _CFLAGS='-std=c89 -O3 -g -Weverything -Wno-long-long'
116 elif [ -z "${_CFLAGS}" ]; then
117 _CFLAGS=-O1
120 if nwantfeat DEBUG; then
121 _CFLAGS="${_CFLAGS} -DNDEBUG"
122 else
123 _CFLAGS="${_CFLAGS} -g";
124 if [ "${stackprot}" = yes ]; then
125 _CFLAGS="${_CFLAGS} -fstack-protector-all "
126 _CFLAGS="${_CFLAGS} -Wstack-protector -D_FORTIFY_SOURCE=2"
129 _CFLAGS="${_CFLAGS} ${ADDCFLAGS}"
130 _LDFLAGS="${_LDFLAGS} ${ADDLDFLAGS}" # XXX -Wl,--sort-common,[-O1]
131 export _CFLAGS _LDFLAGS
133 # $CFLAGS and $LDFLAGS are only overwritten if explicitly wanted
134 if wantfeat AUTOCC; then
135 CFLAGS=$_CFLAGS
136 LDFLAGS=$_LDFLAGS
137 export CFLAGS LDFLAGS
141 ## -- >8 -- 8< -- ##
143 ## Notes:
144 ## - Heirloom sh(1) (and same origin) have problems with ': >' redirection,
145 ## so use "printf '' >" instead
146 ## - Heirloom sh(1) and maybe more execute loops with redirection in a subshell
147 ## (but don't export eval's from within), therefore we need to (re)include
148 ## variable assignments at toplevel instead (via reading temporary files)
150 ## First of all, create new configuration and check wether it changed ##
152 conf=./conf.rc
153 lst=./config.lst
154 h=./config.h
155 mk=./mk.mk
157 newlst=./config.lst-new
158 newmk=./config.mk-new
159 newh=./config.h-new
160 tmp0=___tmp
161 tmp=./${tmp0}1$$
163 # We need some standard utilities
164 unset -f command
165 check_tool() {
166 n=$1 i=$2 opt=${3:-0}
167 if type "${i}" >/dev/null 2>&1; then
168 eval ${n}=${i}
169 return 1
171 if [ ${opt} -eq 0 ]; then
172 echo >&2 "ERROR: no trace of the utility \`${n}'"
173 exit 1
175 return 0
178 # Check those tools right now that we need before including ${conf}
179 check_tool rm "${rm:-`command -pv rm`}"
180 check_tool sed "${sed:-`command -pv sed`}"
182 # Only incorporate what wasn't overwritten from command line / CONFIG
183 trap "${rm} -f ${tmp}; exit" 1 2 15
184 trap "${rm} -f ${tmp}" 0
185 ${rm} -f ${tmp}
187 < ${conf} ${sed} -e '/^[ \t]*#/d' -e '/^$/d' -e 's/[ \t]*$//' |
188 while read line; do
189 i=`echo ${line} | ${sed} -e 's/=.*$//'`
190 eval j=\$${i} jx=\${${i}+x}
191 if [ -n "${j}" ] || [ "${jx}" = x ]; then
192 line="${i}=\"${j}\""
194 echo ${line}
195 done > ${tmp}
196 . ./${tmp}
198 check_tool awk "${awk:-`command -pv awk`}"
199 check_tool cat "${cat:-`command -pv cat`}"
200 check_tool chmod "${chmod:-`command -pv chmod`}"
201 check_tool cp "${cp:-`command -pv cp`}"
202 check_tool cmp "${cmp:-`command -pv cmp`}"
203 check_tool grep "${grep:-`command -pv grep`}"
204 check_tool mkdir "${mkdir:-`command -pv mkdir`}"
205 check_tool mv "${mv:-`command -pv mv`}"
206 # rm(1), sed(1) above
207 check_tool tee "${tee:-`command -pv tee`}"
209 check_tool make "${MAKE:-`command -pv make`}"
210 check_tool strip "${STRIP:-`command -pv strip`}" 1
211 HAVE_STRIP=${?}
213 wantfeat() {
214 eval i=\$WANT_${1}
215 [ "${i}" = "1" ]
217 nwantfeat() {
218 eval i=\$WANT_${1}
219 [ "${i}" != "1" ]
222 option_update
224 # (No function since some shells loose non-exported variables in traps)
225 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}; exit" 1 2 15
226 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}" 0
227 ${rm} -f ${newlst} ${newmk} ${newh}
229 # (Could: use FD redirection, add eval(1) and don't re-'. ./${newlst}')
230 while read line; do
231 i=`echo ${line} | ${sed} -e 's/=.*$//'`
232 eval j=\$${i}
233 if [ -z "${j}" ] || [ "${j}" = 0 ]; then
234 printf "/*#define ${i}*/\n" >> ${newh}
235 elif [ "${j}" = 1 ]; then
236 printf "#define ${i}\n" >> ${newh}
237 else
238 printf "#define ${i} \"${j}\"\n" >> ${newh}
240 printf "${i} = ${j}\n" >> ${newmk}
241 printf "${i}=\"${j}\"\n"
242 done < ${tmp} > ${newlst}
243 . ./${newlst}
245 printf "#define UAGENT \"${SID}${NAIL}\"\n" >> ${newh}
246 printf "UAGENT = ${SID}${NAIL}\n" >> ${newmk}
248 compiler_flags
250 printf "CC = ${CC}\n" >> ${newmk}
251 printf "_CFLAGS = ${_CFLAGS}\nCFLAGS = ${CFLAGS}\n" >> ${newmk}
252 printf "_LDFLAGS = ${_LDFLAGS}\nLDFLAGS = ${LDFLAGS}\n" >> ${newmk}
253 printf "AWK = ${awk}\nCMP = ${cmp}\nCHMOD = ${chmod}\nCP = ${cp}\n" >> ${newmk}
254 printf "MKDIR = ${mkdir}\nRM = ${rm}\nSED = ${sed}\n" >> ${newmk}
255 printf "STRIP = ${strip}\nHAVE_STRIP = ${HAVE_STRIP}\n" >> ${newmk}
256 # (We include the cc(1)/ld(1) environment only for update detection..)
257 printf "CC=\"${CC}\"\n" >> ${newlst}
258 printf "_CFLAGS=\"${_CFLAGS}\"\nCFLAGS=\"${CFLAGS}\"\n" >> ${newlst}
259 printf "_LDFLAGS=\"${_LDFLAGS}\"\nLDFLAGS=\"${LDFLAGS}\"\n" >> ${newlst}
260 printf "AWK=${awk}\nCMP=${cmp}\nCHMOD=${chmod}\nCP=${cp}\n" >> ${newlst}
261 printf "MKDIR=${mkdir}\nRM=${rm}\nSED=${sed}\n" >> ${newlst}
262 printf "STRIP=${strip}\nHAVE_STRIP=${HAVE_STRIP}\n" >> ${newlst}
264 if [ -f ${lst} ] && ${cmp} ${newlst} ${lst} >/dev/null 2>&1; then
265 exit 0
267 [ -f ${lst} ] && echo 'configuration updated..' || echo 'shiny configuration..'
269 ${mv} -f ${newlst} ${lst}
270 ${mv} -f ${newh} ${h}
271 ${mv} -f ${newmk} ${mk}
273 ## Compile and link checking ##
275 tmp2=./${tmp0}2$$
276 tmp3=./${tmp0}3$$
277 log=./config.log
278 lib=./config.lib
279 inc=./config.inc
280 src=./config.c
281 makefile=./config.mk
283 # (No function since some shells loose non-exported variables in traps)
284 trap "${rm} -f ${lst} ${h} ${mk} ${lib} ${inc} ${src} ${makefile}; exit" 1 2 15
285 trap "${rm} -rf ${tmp0}.* ${tmp0}* ${makefile}" 0
287 exec 5>&2 > ${log} 2>&1
288 printf '' > ${lib}
289 printf '' > ${inc}
290 # ${src} is only created if WANT_AMALGAMATION
291 ${rm} -f ${src}
292 ${cat} > ${makefile} << \!
293 .SUFFIXES: .o .c .x .y
294 .c.o:
295 $(CC) $(XINCS) -c $<
296 .c.x:
297 $(CC) $(XINCS) -E $< >$@
299 $(CC) $(XINCS) -o $@ $< $(XLIBS)
300 .y: ;
303 msg() {
304 fmt=$1
306 shift
307 printf "*** ${fmt}\\n" "${@}"
308 printf "${fmt}" "${@}" >&5
311 _check_preface() {
312 variable=$1 topic=$2 define=$3
314 echo '**********'
315 msg "checking ${topic} ... "
316 echo "/* checked ${topic} */" >> ${h}
317 ${rm} -f ${tmp} ${tmp}.o
318 echo '*** test program is'
319 ${tee} ${tmp}.c
320 #echo '*** the preprocessor generates'
321 #${make} -f ${makefile} ${tmp}.x
322 #${cat} ${tmp}.x
323 echo '*** results are'
326 compile_check() {
327 variable=$1 topic=$2 define=$3
329 _check_preface "${variable}" "${topic}" "${define}"
331 if ${make} -f ${makefile} XINCS="${INCS}" ./${tmp}.o &&
332 [ -f ./${tmp}.o ]; then
333 msg "yes\\n"
334 echo "${define}" >> ${h}
335 eval have_${variable}=yes
336 return 0
337 else
338 echo "/* ${define} */" >> ${h}
339 msg "no\\n"
340 eval unset have_${variable}
341 return 1
345 _link_mayrun() {
346 run=$1 variable=$2 topic=$3 define=$4 libs=$5 incs=$6
348 _check_preface "${variable}" "${topic}" "${define}"
350 if ${make} -f ${makefile} XINCS="${INCS} ${incs}" \
351 XLIBS="${LIBS} ${libs}" ./${tmp} &&
352 [ -f ./${tmp} ] &&
353 { [ ${run} -eq 0 ] || ./${tmp}; }; then
354 echo "*** adding INCS<${incs}> LIBS<${libs}>"
355 msg "yes\\n"
356 echo "${define}" >> ${h}
357 LIBS="${LIBS} ${libs}"
358 echo "${libs}" >> ${lib}
359 INCS="${INCS} ${incs}"
360 echo "${incs}" >> ${inc}
361 eval have_${variable}=yes
362 return 0
363 else
364 msg "no\\n"
365 echo "/* ${define} */" >> ${h}
366 eval unset have_${variable}
367 return 1
371 link_check() {
372 _link_mayrun 0 "${1}" "${2}" "${3}" "${4}" "${5}"
375 run_check() {
376 _link_mayrun 1 "${1}" "${2}" "${3}" "${4}" "${5}"
379 # Build a basic set of INCS and LIBS according to user environment.
380 # On pkgsrc(7) systems automatically add /usr/pkg/*
381 if [ -n "${C_INCLUDE_PATH}" ]; then
382 i=${IFS}
383 IFS=:
384 set -- ${C_INCLUDE_PATH}
385 IFS=${i}
386 # for i; do -- new in POSIX Issue 7 + TC1
387 for i
389 [ "${i}" = '/usr/pkg/include' ] && continue
390 INCS="${INCS} -I${i}"
391 done
393 [ -d /usr/pkg/include ] && INCS="${INCS} -I/usr/pkg/include"
394 echo "${INCS}" >> ${inc}
396 if [ -n "${LD_LIBRARY_PATH}" ]; then
397 i=${IFS}
398 IFS=:
399 set -- ${LD_LIBRARY_PATH}
400 IFS=${i}
401 # for i; do -- new in POSIX Issue 7 + TC1
402 for i
404 [ "${i}" = '/usr/pkg/lib' ] && continue
405 LIBS="${LIBS} -L${i}"
406 done
408 [ -d /usr/pkg/lib ] && LIBS="${LIBS} -L/usr/pkg/lib"
409 echo "${LIBS}" >> ${lib}
413 # Better set _GNU_SOURCE (if we are on Linux only?); 'surprised it did without
414 echo '#define _GNU_SOURCE' >> ${h}
416 link_check hello 'if a hello world program can be built' << \! || {\
417 echo >&5 'This oooops is most certainly not related to me.';\
418 echo >&5 "Read the file ${log} and check your compiler environment.";\
419 ${rm} -f ${lst} ${h} ${mk};\
420 exit 1;\
422 #include <stdio.h>
424 int main(int argc, char *argv[])
426 (void)argc;
427 (void)argv;
428 puts("hello world");
429 return 0;
433 link_check termios 'for termios.h and tc*() family' << \! || {\
434 echo >&5 'We require termios.h and the tc*() family of functions.';\
435 echo >&5 "That much Unix we indulge ourselfs.";\
436 ${rm} -f ${lst} ${h} ${mk};\
437 exit 1;\
439 #include <termios.h>
440 int main(void)
442 struct termios tios;
443 tcgetattr(0, &tios);
444 tcsetattr(0, TCSADRAIN | TCSAFLUSH, &tios);
445 return 0;
449 link_check snprintf 'for snprintf()' '#define HAVE_SNPRINTF' << \!
450 #include <stdio.h>
451 int main(void)
453 char b[20];
454 snprintf(b, sizeof b, "%s", "string");
455 return 0;
459 link_check putc_unlocked 'for putc_unlocked()' '#define HAVE_PUTC_UNLOCKED' <<\!
460 #include <stdio.h>
461 int main(void)
463 putc_unlocked('@', stdout);
464 return 0;
468 link_check fchdir 'for fchdir()' '#define HAVE_FCHDIR' << \!
469 #include <unistd.h>
470 int main(void)
472 fchdir(0);
473 return 0;
477 link_check mmap 'for mmap()' '#define HAVE_MMAP' << \!
478 #include <sys/types.h>
479 #include <sys/mman.h>
480 int main(void)
482 mmap(0, 0, 0, 0, 0, 0);
483 return 0;
487 link_check mremap 'for mremap()' '#define HAVE_MREMAP' << \!
488 #include <sys/types.h>
489 #include <sys/mman.h>
490 int main(void)
492 mremap(0, 0, 0, MREMAP_MAYMOVE);
493 return 0;
497 link_check setlocale 'for setlocale()' '#define HAVE_SETLOCALE' << \!
498 #include <locale.h>
499 int main(void)
501 setlocale(LC_ALL, "");
502 return 0;
506 if [ "${have_setlocale}" = yes ]; then
507 link_check c90amend1 'for ISO/IEC 9899:1990/Amendment 1:1995' \
508 '#define HAVE_C90AMEND1' << \!
509 #include <limits.h>
510 #include <stdlib.h>
511 #include <wchar.h>
512 #include <wctype.h>
513 int main(void)
515 char mbb[MB_LEN_MAX + 1];
516 wchar_t wc;
517 iswprint(L'c');
518 towupper(L'c');
519 mbtowc(&wc, "x", 1);
520 mbrtowc(&wc, "x", 1, NULL);
521 (void)wctomb(mbb, wc);
522 return (mblen("\0", 1) == 0);
526 if [ "${have_c90amend1}" = yes ]; then
527 link_check wcwidth 'for wcwidth()' '#define HAVE_WCWIDTH' << \!
528 #include <wchar.h>
529 int main(void)
531 wcwidth(L'c');
532 return 0;
537 link_check nl_langinfo 'for nl_langinfo()' '#define HAVE_NL_LANGINFO' << \!
538 #include <langinfo.h>
539 #include <stdlib.h>
540 int main(void)
542 nl_langinfo(DAY_1);
543 return (nl_langinfo(CODESET) == NULL);
546 fi # have_setlocale
548 link_check mkstemp 'for mkstemp()' '#define HAVE_MKSTEMP' << \!
549 #include <stdlib.h>
550 int main(void)
552 mkstemp("x");
553 return 0;
557 # Note: run_check, thus we also get only the desired implementation...
558 run_check realpath 'for realpath()' '#define HAVE_REALPATH' << \!
559 #include <stdlib.h>
560 int main(void)
562 char *x = realpath(".", NULL), *y = realpath("/", NULL);
563 return (x != NULL && y != NULL) ? 0 : 1;
567 link_check wordexp 'for wordexp()' '#define HAVE_WORDEXP' << \!
568 #include <wordexp.h>
569 int main(void)
571 wordexp((char *)0, (wordexp_t *)0, 0);
572 return 0;
578 if wantfeat DEBUG; then
579 echo '#define HAVE_DEBUG' >> ${h}
582 if wantfeat AMALGAMATION; then
583 echo '#define HAVE_AMALGAMATION' >> ${h}
586 if nwantfeat NOALLOCA; then
587 # Due to NetBSD PR lib/47120 it seems best not to use non-cc-builtin
588 # versions of alloca(3) since modern compilers just can't be trusted
589 # not to overoptimize and silently break some code
590 link_check alloca 'for __builtin_alloca()' \
591 '#define HAVE_ALLOCA __builtin_alloca' << \!
592 int main(void)
594 void *vp = __builtin_alloca(1);
595 return (!! vp);
600 if nwantfeat NOGETOPT; then
601 link_check getopt 'for getopt()' '#define HAVE_GETOPT' << \!
602 #include <unistd.h>
603 int main(int argc, char **argv)
605 #if defined __GLIBC__ || defined __linux__
606 Argument and option reordering is not a desired feature.
607 #else
608 getopt(argc, argv, "oPt");
609 #endif
610 return (((long)optarg + optind) & 0x7F);
617 if wantfeat ICONV; then
618 ${cat} > ${tmp2}.c << \!
619 #include <iconv.h>
620 int main(void)
622 iconv_t id;
624 id = iconv_open("foo", "bar");
625 return 0;
628 < ${tmp2}.c link_check iconv 'for iconv functionality' \
629 '#define HAVE_ICONV' ||
630 < ${tmp2}.c link_check iconv \
631 'for iconv functionality in libiconv' \
632 '#define HAVE_ICONV' '-liconv'
633 else
634 echo '/* WANT_ICONV=0 */' >> ${h}
635 fi # wantfeat ICONV
637 if wantfeat SOCKETS; then
638 compile_check arpa_inet_h 'for <arpa/inet.h>' \
639 '#define HAVE_ARPA_INET_H' << \!
640 #include "config.h"
641 #include <sys/types.h>
642 #include <sys/socket.h>
643 #include <netdb.h>
644 #include <netinet/in.h>
645 #include <arpa/inet.h>
648 ${cat} > ${tmp2}.c << \!
649 #include "config.h"
650 #include <sys/types.h>
651 #include <sys/socket.h>
652 #include <netdb.h>
653 #include <netinet/in.h>
654 #ifdef HAVE_ARPA_INET_H
655 #include <arpa/inet.h>
656 #endif
658 int main(void)
660 struct sockaddr s;
661 socket(AF_INET, SOCK_STREAM, 0);
662 connect(0, &s, 0);
663 gethostbyname("foo");
664 return 0;
668 < ${tmp2}.c link_check sockets 'for sockets in libc' \
669 '#define HAVE_SOCKETS' ||
670 < ${tmp2}.c link_check sockets 'for sockets in libnsl' \
671 '#define HAVE_SOCKETS' '-lnsl' ||
672 < ${tmp2}.c link_check sockets \
673 'for sockets in libsocket and libnsl' \
674 '#define HAVE_SOCKETS' '-lsocket -lnsl' ||
675 WANT_SOCKETS=0
677 # XXX Shouldn't it be a hard error if there is no socket support, then?
678 option_update
679 else
680 echo '/* WANT_SOCKETS=0 */' >> ${h}
681 fi # wantfeat SOCKETS
683 wantfeat SOCKETS &&
684 link_check setsockopt 'for setsockopt()' '#define HAVE_SETSOCKOPT' << \!
685 #include <sys/socket.h>
686 #include <stdlib.h>
687 int main(void)
689 int sockfd = 3;
690 setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0);
691 return 0;
695 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
696 link_check so_sndtimeo 'for SO_SNDTIMEO' '#define HAVE_SO_SNDTIMEO' << \!
697 #include <sys/socket.h>
698 #include <stdlib.h>
699 int main(void)
701 struct timeval tv;
702 int sockfd = 3;
703 tv.tv_sec = 42;
704 tv.tv_usec = 21;
705 setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
706 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
707 return 0;
711 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
712 link_check so_linger 'for SO_LINGER' '#define HAVE_SO_LINGER' << \!
713 #include <sys/socket.h>
714 #include <stdlib.h>
715 int main(void)
717 struct linger li;
718 int sockfd = 3;
719 li.l_onoff = 1;
720 li.l_linger = 42;
721 setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &li, sizeof li);
722 return 0;
726 if wantfeat IPV6; then
727 link_check ipv6 'for IPv6 functionality' '#define HAVE_IPV6' << \!
728 #include "config.h"
729 #include <sys/types.h>
730 #include <sys/socket.h>
731 #include <netdb.h>
732 #include <netinet/in.h>
733 #ifdef HAVE_ARPA_INET_H
734 #include <arpa/inet.h>
735 #endif
737 int main(void)
739 struct addrinfo a, *ap;
740 getaddrinfo("foo", "0", &a, &ap);
741 return 0;
744 else
745 echo '/* WANT_IPV6=0 */' >> ${h}
746 fi # wantfeat IPV6
748 if wantfeat IMAP; then
749 echo '#define HAVE_IMAP' >> ${h}
750 else
751 echo '/* WANT_IMAP=0 */' >> ${h}
754 if wantfeat POP3; then
755 echo '#define HAVE_POP3' >> ${h}
756 else
757 echo '/* WANT_POP3=0 */' >> ${h}
760 if wantfeat SMTP; then
761 echo '#define HAVE_SMTP' >> ${h}
762 else
763 echo '/* WANT_SMTP=0 */' >> ${h}
766 if wantfeat SSL; then
767 link_check openssl 'for sufficiently recent OpenSSL' \
768 '#define HAVE_SSL
769 #define HAVE_OPENSSL' '-lssl -lcrypto' << \!
770 #include <openssl/ssl.h>
771 #include <openssl/err.h>
772 #include <openssl/x509v3.h>
773 #include <openssl/x509.h>
774 #include <openssl/rand.h>
776 #if defined OPENSSL_NO_SSL2 && defined OPENSSL_NO_SSL3 &&\
777 defined OPENSSL_NO_TLS1
778 # error We need one of (SSLv2 and) SSLv3 and TLS1.
779 #endif
781 int main(void)
783 SSLv23_client_method();
784 #ifndef OPENSSL_NO_SSL3
785 SSLv3_client_method();
786 #endif
787 #ifndef OPENSSL_NO_TLS1
788 TLSv1_client_method();
789 # ifdef TLS1_1_VERSION
790 TLSv1_1_client_method();
791 # endif
792 # ifdef TLS1_2_VERSION
793 TLSv1_2_client_method();
794 # endif
795 #endif
796 PEM_read_PrivateKey(0, 0, 0, 0);
797 return 0;
801 if [ "${have_openssl}" = 'yes' ]; then
802 compile_check stack_of 'for OpenSSL STACK_OF()' \
803 '#define HAVE_STACK_OF' << \!
804 #include <openssl/ssl.h>
805 #include <openssl/err.h>
806 #include <openssl/x509v3.h>
807 #include <openssl/x509.h>
808 #include <openssl/rand.h>
810 int main(void)
812 STACK_OF(GENERAL_NAME) *gens = NULL;
813 printf("%p", gens); /* to make it used */
814 return 0;
818 run_check openssl_md5 'for MD5 digest in OpenSSL' \
819 '#define HAVE_OPENSSL_MD5' << \!
820 #include <string.h>
821 #include <openssl/md5.h>
823 int main(void)
825 char const dat[] = "abrakadabrafidibus";
826 char dig[16], hex[16 * 2];
827 MD5_CTX ctx;
828 size_t i, j;
830 memset(dig, 0, sizeof(dig));
831 memset(hex, 0, sizeof(hex));
832 MD5_Init(&ctx);
833 MD5_Update(&ctx, dat, sizeof(dat) - 1);
834 MD5_Final(dig, &ctx);
836 #define hexchar(n) ((n)>9 ? (n)-10+'a' : (n)+'0')
837 for (i = 0; i < sizeof(hex) / 2; i++) {
838 j = i << 1;
839 hex[j] = hexchar((dig[i] & 0xf0) >> 4);
840 hex[++j] = hexchar(dig[i] & 0x0f);
842 return !!memcmp("6d7d0a3d949da2e96f2aa010f65d8326", hex, sizeof(hex));
847 else
848 echo '/* WANT_SSL=0 */' >> ${h}
849 fi # wantfeat SSL
851 if wantfeat GSSAPI; then
852 ${cat} > ${tmp2}.c << \!
853 #include <gssapi/gssapi.h>
855 int main(void)
857 gss_import_name(0, 0, GSS_C_NT_HOSTBASED_SERVICE, 0);
858 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
859 return 0;
862 ${sed} -e '1s/gssapi\///' < ${tmp2}.c > ${tmp3}.c
864 if command -v krb5-config >/dev/null 2>&1; then
865 i=`command -v krb5-config`
866 GSSAPI_LIBS="`CFLAGS= ${i} --libs gssapi`"
867 GSSAPI_INCS="`CFLAGS= ${i} --cflags`"
868 i='for GSSAPI via krb5-config(1)'
869 else
870 GSSAPI_LIBS='-lgssapi'
871 GSSAPI_INCS=
872 i='for GSSAPI in gssapi/gssapi.h, libgssapi'
874 < ${tmp2}.c link_check gssapi \
875 "${i}" '#define HAVE_GSSAPI' \
876 "${GSSAPI_LIBS}" "${GSSAPI_INCS}" ||\
877 < ${tmp3}.c link_check gssapi \
878 'for GSSAPI in gssapi.h, libgssapi' \
879 '#define HAVE_GSSAPI
880 #define GSSAPI_REG_INCLUDE' \
881 '-lgssapi' ||\
882 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgssapi_krb5' \
883 '#define HAVE_GSSAPI' \
884 '-lgssapi_krb5' ||\
885 < ${tmp3}.c link_check gssapi \
886 'for GSSAPI in libgssapi, OpenBSD-style (pre 5.3)' \
887 '#define HAVE_GSSAPI
888 #define GSSAPI_REG_INCLUDE' \
889 '-lgssapi -lkrb5 -lcrypto' \
890 '-I/usr/include/kerberosV' ||\
891 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgss' \
892 '#define HAVE_GSSAPI' \
893 '-lgss' ||\
894 link_check gssapi 'for GSSAPI in libgssapi_krb5, old-style' \
895 '#define HAVE_GSSAPI
896 #define GSSAPI_OLD_STYLE' \
897 '-lgssapi_krb5' << \!
898 #include <gssapi/gssapi.h>
899 #include <gssapi/gssapi_generic.h>
901 int main(void)
903 gss_import_name(0, 0, gss_nt_service_name, 0);
904 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
905 return 0;
908 else
909 echo '/* WANT_GSSAPI=0 */' >> ${h}
910 fi # wantfeat GSSAPI
912 if wantfeat IDNA; then
913 link_check idna 'for GNU Libidn' '#define HAVE_IDNA' '-lidn' << \!
914 #include <idna.h>
915 #include <stringprep.h>
916 int main(void)
918 char *utf8, *idna_ascii, *idna_utf8;
919 utf8 = stringprep_locale_to_utf8("does.this.work");
920 if (idna_to_ascii_8z(utf8, &idna_ascii, IDNA_USE_STD3_ASCII_RULES)
921 != IDNA_SUCCESS)
922 return 1;
923 /* (Rather link check only here) */
924 idna_utf8 = stringprep_convert(idna_ascii, "UTF-8", "de_DE");
925 return 0;
928 else
929 echo '/* WANT_IDNA=0 */' >> ${h}
932 if wantfeat REGEX; then
933 link_check regex 'for regular expressions' '#define HAVE_REGEX' << \!
934 #include <regex.h>
935 #include <stdlib.h>
936 int main(void)
938 int status;
939 regex_t re;
940 if (regcomp(&re, ".*bsd", REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
941 return 1;
942 status = regexec(&re, "plan9", 0,NULL, 0);
943 regfree(&re);
944 return !(status == REG_NOMATCH);
947 else
948 echo '/* WANT_REGEX=0 */' >> ${h}
951 if wantfeat READLINE; then
952 __edrdlib() {
953 link_check readline "for readline(3) (${1})" \
954 '#define HAVE_READLINE' "${1}" << \!
955 #include <stdio.h>
956 #include <readline/history.h>
957 #include <readline/readline.h>
958 int main(void)
960 char *rl;
961 using_history();
962 read_history("");
963 stifle_history(242);
964 rl = readline("Enter a line:");
965 if (rl && *rl)
966 add_history(rl);
967 write_history("");
968 rl_extend_line_buffer(10);
969 rl_point = rl_end = 10;
970 rl_pre_input_hook = (rl_hook_func_t*)NULL;
971 rl_forced_update_display();
973 rl_free_line_state();
974 rl_cleanup_after_signal();
975 rl_reset_after_signal();
976 return 0;
981 __edrdlib -lreadline ||
982 __edrdlib '-lreadline -ltermcap'
983 [ -n "${have_readline}" ] && WANT_TABEXPAND=1
986 if wantfeat EDITLINE && [ -z "${have_readline}" ]; then
987 __edlib() {
988 link_check editline "for editline(3) (${1})" \
989 '#define HAVE_EDITLINE' "${1}" << \!
990 #include <histedit.h>
991 static char * getprompt(void) { return (char*)"ok"; }
992 int main(void)
994 HistEvent he;
995 EditLine *el_el = el_init("TEST", stdin, stdout, stderr);
996 History *el_hcom = history_init();
997 history(el_hcom, &he, H_SETSIZE, 242);
998 el_set(el_el, EL_SIGNAL, 0);
999 el_set(el_el, EL_TERMINAL, NULL);
1000 el_set(el_el, EL_HIST, &history, el_hcom);
1001 el_set(el_el, EL_EDITOR, "emacs");
1002 el_set(el_el, EL_PROMPT, &getprompt);
1003 el_source(el_el, NULL);
1004 el_end(el_el);
1005 /* TODO add loader and addfn checks */
1006 history_end(el_hcom);
1007 return 0;
1012 __edlib -ledit ||
1013 __edlib '-ledit -ltermcap'
1014 [ -n "${have_editline}" ] && WANT_TABEXPAND=0
1017 if wantfeat NCL && [ -z "${have_editline}" ] && [ -z "${have_readline}" ] &&\
1018 [ -n "${have_c90amend1}" ]; then
1019 have_ncl=1
1020 echo '#define HAVE_NCL' >> ${h}
1021 else
1022 echo '/* WANT_{READLINE,EDITLINE,NCL}=0 */' >> ${h}
1025 if [ -n "${have_ncl}" ] || [ -n "${have_editline}" ] ||\
1026 [ -n "${have_readline}" ]; then
1027 have_cle=1
1030 if [ -n "${have_cle}" ] && wantfeat TABEXPAND; then
1031 echo '#define HAVE_TABEXPAND' >> ${h}
1032 else
1033 echo '/* WANT_TABEXPAND=0 */' >> ${h}
1036 if [ -n "${have_cle}" ] && wantfeat HISTORY; then
1037 echo '#define HAVE_HISTORY' >> ${h}
1038 else
1039 echo '/* WANT_HISTORY=0 */' >> ${h}
1042 if wantfeat QUOTE_FOLD &&\
1043 [ -n "${have_c90amend1}" ] && [ -n "${have_wcwidth}" ]; then
1044 echo '#define HAVE_QUOTE_FOLD' >> ${h}
1045 else
1046 echo '/* WANT_QUOTE_FOLD=0 */' >> ${h}
1049 if wantfeat DOCSTRINGS; then
1050 echo '#define HAVE_DOCSTRINGS' >> ${h}
1051 else
1052 echo '/* WANT_DOCSTRINGS=0 */' >> ${h}
1055 if wantfeat SPAM; then
1056 echo '#define HAVE_SPAM' >> ${h}
1057 if command -v spamc >/dev/null 2>&1; then
1058 echo "#define SPAMC_PATH \"`command -v spamc`\"" >> ${h}
1060 else
1061 echo '/* WANT_SPAM=0 */' >> ${h}
1064 if wantfeat MD5; then
1065 echo '#define HAVE_MD5' >> ${h}
1066 else
1067 echo '/* WANT_MD5=0 */' >> ${h}
1070 ## Summarizing ##
1072 # Since we cat(1) the content of those to cc/"ld", convert them to single line
1073 squeeze_em() {
1074 < "${1}" > "${2}" ${awk} \
1075 'BEGIN {ORS = " "} /^[^#]/ {print} {next} END {ORS = ""; print "\n"}'
1077 ${rm} -f ${tmp}
1078 squeeze_em ${inc} ${tmp}
1079 ${mv} ${tmp} ${inc}
1080 squeeze_em ${lib} ${tmp}
1081 ${mv} ${tmp} ${lib}
1083 # config.h
1084 ${mv} ${h} ${tmp}
1085 printf '#ifndef _CONFIG_H\n# define _CONFIG_H\n' > ${h}
1086 ${cat} ${tmp} >> ${h}
1088 printf '\n/* The "feature string", for "simplicity" and lex.c */\n' >> ${h}
1089 printf '#ifdef _MAIN_SOURCE\n' >> ${h}
1090 printf '# ifdef HAVE_AMALGAMATION\nstatic\n# endif\n' >> ${h}
1091 printf 'char const features[] = "MIME"\n' >> ${h}
1092 printf '# ifdef HAVE_DOCSTRINGS\n ",DOCSTRINGS"\n# endif\n' >> ${h}
1093 printf '# ifdef HAVE_ICONV\n ",ICONV"\n# endif\n' >> ${h}
1094 printf '# ifdef HAVE_SETLOCALE\n ",LOCALES"\n# endif\n' >> ${h}
1095 printf '# ifdef HAVE_C90AMEND1\n ",MULTIBYTE CHARSETS"\n# endif\n' >> ${h}
1096 printf '# ifdef HAVE_NL_LANGINFO\n ",TERMINAL CHARSET"\n# endif\n' >> ${h}
1097 printf '# ifdef HAVE_SOCKETS\n ",NETWORK"\n# endif\n' >> ${h}
1098 printf '# ifdef HAVE_IPV6\n ",IPv6"\n# endif\n' >> ${h}
1099 printf '# ifdef HAVE_SSL\n ",S/MIME,SSL/TSL"\n# endif\n' >> ${h}
1100 printf '# ifdef HAVE_IMAP\n ",IMAP"\n# endif\n' >> ${h}
1101 printf '# ifdef HAVE_GSSAPI\n ",GSSAPI"\n# endif\n' >> ${h}
1102 printf '# ifdef HAVE_POP3\n ",POP3"\n# endif\n' >> ${h}
1103 printf '# ifdef HAVE_SMTP\n ",SMTP"\n# endif\n' >> ${h}
1104 printf '# ifdef HAVE_SPAM\n ",SPAM"\n# endif\n' >> ${h}
1105 printf '# ifdef HAVE_IDNA\n ",IDNA"\n# endif\n' >> ${h}
1106 printf '# ifdef HAVE_REGEX\n ",REGEX"\n# endif\n' >> ${h}
1107 printf '# ifdef HAVE_READLINE\n ",READLINE"\n# endif\n' >> ${h}
1108 printf '# ifdef HAVE_EDITLINE\n ",EDITLINE"\n# endif\n' >> ${h}
1109 printf '# ifdef HAVE_NCL\n ",NCL"\n# endif\n' >> ${h}
1110 printf '# ifdef HAVE_TABEXPAND\n ",TABEXPAND"\n# endif\n' >> ${h}
1111 printf '# ifdef HAVE_HISTORY\n ",HISTORY MANAGEMENT"\n# endif\n' >> ${h}
1112 printf '# ifdef HAVE_QUOTE_FOLD\n ",QUOTE-FOLD"\n# endif\n' >> ${h}
1113 printf '# ifdef HAVE_DEBUG\n ",DEBUG"\n# endif\n' >> ${h}
1114 printf ';\n#endif /* _MAIN_SOURCE */\n' >> ${h}
1116 printf '#endif /* _CONFIG_H */\n' >> ${h}
1117 ${rm} -f ${tmp}
1119 # Create the real mk.mk
1120 ${rm} -rf ${tmp0}.* ${tmp0}*
1121 printf 'OBJ_SRC = ' >> ${mk}
1122 if nwantfeat AMALGAMATION; then
1123 echo *.c >> ${mk}
1124 echo 'OBJ_DEP =' >> ${mk}
1125 else
1126 j=`echo "${src}" | sed 's/^.\///'`
1127 echo "${j}" >> ${mk}
1128 printf 'OBJ_DEP = main.c ' >> ${mk}
1129 printf '#define _MAIN_SOURCE\n' >> ${src}
1130 printf '#include "nail.h"\n#include "main.c"\n' >> ${src}
1131 for i in *.c; do
1132 if [ "${i}" = "${j}" ] || [ "${i}" = main.c ]; then
1133 continue
1135 printf "${i} " >> ${mk}
1136 printf "#include \"${i}\"\n" >> ${src}
1137 done
1138 echo >> ${mk}
1141 echo "LIBS = `${cat} ${lib}`" >> ${mk}
1142 echo "INCLUDES = `${cat} ${inc}`" >> ${mk}
1143 echo >> ${mk}
1144 ${cat} ./mk-mk.in >> ${mk}
1146 ## Finished! ##
1148 ${cat} > ${tmp2}.c << \!
1149 #include "config.h"
1150 #ifdef HAVE_NL_LANGINFO
1151 # include <langinfo.h>
1152 #endif
1154 :The following optional features are enabled:
1155 #ifdef HAVE_ICONV
1156 : + Character set conversion using iconv()
1157 #endif
1158 #ifdef HAVE_SETLOCALE
1159 : + Locale support: Printable characters depend on the environment
1160 # ifdef HAVE_C90AMEND1
1161 : + Multibyte character support
1162 # endif
1163 # ifdef HAVE_NL_LANGINFO
1164 : + Automatic detection of terminal character set
1165 # endif
1166 #endif
1167 #ifdef HAVE_SOCKETS
1168 : + Network support
1169 #endif
1170 #ifdef HAVE_IPV6
1171 : + Support for Internet Protocol v6 (IPv6)
1172 #endif
1173 #ifdef HAVE_SSL
1174 # ifdef HAVE_OPENSSL
1175 : + S/MIME and SSL/TLS using OpenSSL
1176 # endif
1177 #endif
1178 #ifdef HAVE_IMAP
1179 : + IMAP protocol
1180 #endif
1181 #ifdef HAVE_GSSAPI
1182 : + IMAP GSSAPI authentication
1183 #endif
1184 #ifdef HAVE_POP3
1185 : + POP3 protocol
1186 #endif
1187 #ifdef HAVE_SMTP
1188 : + SMTP protocol
1189 #endif
1190 #ifdef HAVE_SPAM
1191 : + Interaction with spam filters
1192 #endif
1193 #ifdef HAVE_IDNA
1194 : + IDNA (internationalized domain names for applications) support
1195 #endif
1196 #ifdef HAVE_REGEX
1197 : + Regular expression searches
1198 #endif
1199 #if defined HAVE_READLINE || defined HAVE_EDITLINE || defined HAVE_NCL
1200 : + Command line editing
1201 # ifdef HAVE_TABEXPAND
1202 : + + Tabulator expansion
1203 # endif
1204 # ifdef HAVE_HISTORY
1205 : + + History management
1206 # endif
1207 #endif
1208 #ifdef HAVE_QUOTE_FOLD
1209 : + Extended *quote-fold*ing
1210 #endif
1212 :The following optional features are disabled:
1213 #ifndef HAVE_ICONV
1214 : - Character set conversion using iconv()
1215 #endif
1216 #ifndef HAVE_SETLOCALE
1217 : - Locale support: Only ASCII characters are recognized
1218 #endif
1219 # ifndef HAVE_C90AMEND1
1220 : - Multibyte character support
1221 # endif
1222 # ifndef HAVE_NL_LANGINFO
1223 : - Automatic detection of terminal character set
1224 # endif
1225 #ifndef HAVE_SOCKETS
1226 : - Network support
1227 #endif
1228 #ifndef HAVE_IPV6
1229 : - Support for Internet Protocol v6 (IPv6)
1230 #endif
1231 #if !defined HAVE_SSL
1232 : - SSL/TLS (network transport authentication and encryption)
1233 #endif
1234 #ifndef HAVE_IMAP
1235 : - IMAP protocol
1236 #endif
1237 #ifndef HAVE_GSSAPI
1238 : - IMAP GSSAPI authentication
1239 #endif
1240 #ifndef HAVE_POP3
1241 : - POP3 protocol
1242 #endif
1243 #ifndef HAVE_SMTP
1244 : - SMTP protocol
1245 #endif
1246 #ifndef HAVE_SPAM
1247 : - Interaction with spam filters
1248 #endif
1249 #ifndef HAVE_IDNA
1250 : - IDNA (internationalized domain names for applications) support
1251 #endif
1252 #ifndef HAVE_REGEX
1253 : - Regular expression searches
1254 #endif
1255 #if !defined HAVE_READLINE && !defined HAVE_EDITLINE && !defined HAVE_NCL
1256 : - Command line editing and history
1257 #endif
1258 #ifndef HAVE_QUOTE_FOLD
1259 : - Extended *quote-fold*ing
1260 #endif
1262 :Remarks:
1263 #ifndef HAVE_SNPRINTF
1264 : . The function snprintf() could not be found. mailx will be compiled to use
1265 : sprintf() instead. This might overflow buffers if input values are larger
1266 : than expected. Use the resulting binary with care or update your system
1267 : environment and start the configuration process again.
1268 #endif
1269 #ifndef HAVE_FCHDIR
1270 : . The function fchdir() could not be found. mailx will be compiled to use
1271 : chdir() instead. This is not a problem unless the current working
1272 : directory of mailx is moved while the IMAP cache is used.
1273 #endif
1274 #ifndef HAVE_GETOPT
1275 : . Using a minimal builtin POSIX-like getopt()
1276 #endif
1277 #ifdef HAVE_DEBUG
1278 : . Debug enabled binary: not meant to be used by end-users: THANKS!
1279 #endif
1283 ${make} -f ${makefile} ${tmp2}.x
1284 < ${tmp2}.x >&5 ${sed} -e '/^[^:]/d; /^$/d; s/^://'
1286 # vim:set fenc=utf-8:s-it-mode