Many: unite many HAVE_ to HAVE_C90AMEND1, plus
[s-mailx.git] / mk-conf.sh
blob3f7118d124ea3973df0aafa6d244ae30673bd9cf
1 #!/bin/sh -
2 #@ Please see `INSTALL' and `conf.rc' instead.
4 LC_ALL=C
5 export LC_ALL
7 awk=`command -pv awk`
8 cat=`command -pv cat`
9 chmod=`command -pv chmod`
10 cp=`command -pv cp`
11 cmp=`command -pv cmp`
12 grep=`command -pv grep`
13 make="${MAKE:-`command -pv make`}"
14 mkdir=`command -pv mkdir`
15 mv=`command -pv mv`
16 rm=`command -pv rm`
17 sed=`command -pv sed`
18 tee=`command -pv tee`
20 STRIP=`command -pv strip`
21 [ ${?} -eq 0 ] && HAVE_STRIP=1 || HAVE_STRIP=0
23 # Predefined CONFIG= urations take precedence over anything else
24 if [ -n "${CONFIG}" ]; then
25 case ${CONFIG} in
26 MINIMAL)
27 WANT_SOCKETS=0
28 WANT_IDNA=0
29 WANT_READLINE=0 WANT_EDITLINE=0 WANT_NCL=0
30 WANT_QUOTE_FOLD=0
31 WANT_DOCSTRINGS=0
32 WANT_SPAM=0
34 MEDIUM)
35 WANT_SOCKETS=0
36 WANT_IDNA=0
37 WANT_READLINE=0 WANT_EDITLINE=0
38 WANT_QUOTE_FOLD=0
39 WANT_SPAM=0
41 NETSEND)
42 WANT_IMAP=0
43 WANT_POP3=0
44 WANT_READLINE=0 WANT_EDITLINE=0
45 WANT_QUOTE_FOLD=0
46 WANT_SPAM=0
49 echo >&2 "Unknown CONFIG= setting: ${CONFIG}"
50 echo >&2 'Possible values: MINIMAL, MEDIUM, NETSEND'
51 exit 1
52 esac
55 # Inter-relationships
56 option_update() {
57 if nwantfeat SOCKETS; then
58 WANT_IPV6=0 WANT_SSL=0
59 WANT_IMAP=0 WANT_GSSAPI=0 WANT_POP3=0 WANT_SMTP=0
61 if nwantfeat IMAP && nwantfeat POP3 && nwantfeat SMTP; then
62 WANT_SOCKETS=0 WANT_IPV6=0 WANT_SSL=0
64 if nwantfeat IMAP; then
65 WANT_GSSAPI=0
67 # If we don't need MD5 except for producing boundary and message-id strings,
68 # leave it off, plain old srand(3) should be enough for that purpose.
69 if nwantfeat SOCKETS; then
70 WANT_MD5=0
72 if wantfeat DEBUG; then
73 WANT_NOALLOCA=1
77 # Check out compiler ($CC) and -flags ($CFLAGS)
78 compiler_flags() {
79 i=`uname -s`
80 _CFLAGS=
81 if [ -z "${CC}" ] || [ "${CC}" = cc ]; then
82 _CFLAGS=
83 if { CC="`command -v clang`"; }; then
85 elif { CC="`command -v gcc`"; }; then
87 elif { CC="`command -v c89`"; }; then
88 [ "${i}" = UnixWare ] && _CFLAGS='-v -O'
89 elif { CC="`command -v c99`"; }; then
91 else
92 echo >&2 'ERROR'
93 echo >&2 ' I cannot find a compiler!'
94 echo >&2 ' Neither of clang(1), gcc(1), c89(1) and c99(1).'
95 echo >&2 ' Please set the CC environment variable, maybe CFLAGS also.'
96 exit 1
99 export CC
101 ccver=`${CC} --version 2>/dev/null`
102 stackprot=no
103 if { i=$ccver; echo "${i}"; } | ${grep} -q -i -e gcc -e clang; then
104 #if echo "${i}" | ${grep} -q -i -e gcc -e 'clang version 1'; then
105 stackprot=yes
106 _CFLAGS='-std=c89 -O2'
107 _CFLAGS="${_CFLAGS} -Wall -Wextra -pedantic"
108 _CFLAGS="${_CFLAGS} -fno-unwind-tables -fno-asynchronous-unwind-tables"
109 _CFLAGS="${_CFLAGS} -fstrict-aliasing"
110 _CFLAGS="${_CFLAGS} -Wbad-function-cast -Wcast-align -Wcast-qual"
111 _CFLAGS="${_CFLAGS} -Winit-self -Wshadow -Wunused -Wwrite-strings"
112 if { i=$ccver; echo "${i}"; } | ${grep} -q -e 'clang version 1'; then
114 else
115 _CFLAGS="${_CFLAGS} -fstrict-overflow -Wstrict-overflow=5"
116 if wantfeat AMALGAMATION && nwantfeat DEBUG; then
117 _CFLAGS="${_CFLAGS} -Wno-unused-function"
119 if { i=$ccver; echo "${i}"; } | ${grep} -q -i -e clang; then
120 _CFLAGS="${_CFLAGS} -Wno-unused-result" # TODO handle the right way
123 _CFLAGS="${_CFLAGS} -Wno-long-long" # ISO C89 has no 'long long'...
124 # elif { i=$ccver; echo "${i}"; } | ${grep} -q -i -e clang; then
125 # stackprot=yes
126 # _CFLAGS='-std=c89 -O3 -g -Weverything -Wno-long-long'
127 elif [ -z "${_CFLAGS}" ]; then
128 _CFLAGS=-O1
131 if nwantfeat DEBUG; then
132 _CFLAGS="${_CFLAGS} -DNDEBUG"
133 else
134 _CFLAGS="${_CFLAGS} -g";
135 if [ "${stackprot}" = yes ]; then
136 _CFLAGS="${_CFLAGS} -fstack-protector-all "
137 _CFLAGS="${_CFLAGS} -Wstack-protector -D_FORTIFY_SOURCE=2"
140 _CFLAGS="${_CFLAGS} ${ADDCFLAGS}"
141 _LDFLAGS="${_LDFLAGS} ${ADDLDFLAGS}" # XXX -Wl,--sort-common,[-O1]
142 export _CFLAGS _LDFLAGS
144 if wantfeat AUTOCC; then
145 CFLAGS=$_CFLAGS
146 LDFLAGS=$_LDFLAGS
147 export CFLAGS LDFLAGS
151 ## -- >8 -- 8< -- ##
153 ## Notes:
154 ## - Heirloom sh(1) (and same origin) have problems with ': >' redirection,
155 ## so use "printf '' >" instead
156 ## - Heirloom sh(1) and maybe more execute loops with redirection in a subshell
157 ## (but don't export eval's from within), therefore we need to (re)include
158 ## variable assignments at toplevel instead (via reading temporary files)
160 ## First of all, create new configuration and check wether it changed ##
162 conf=./conf.rc
163 lst=./config.lst
164 h=./config.h
165 mk=./mk.mk
167 newlst=./config.lst-new
168 newmk=./config.mk-new
169 newh=./config.h-new
170 tmp0=___tmp
171 tmp=./${tmp0}1$$
173 # Only incorporate what wasn't overwritten from command line / CONFIG
174 trap "${rm} -f ${tmp}; exit" 1 2 15
175 trap "${rm} -f ${tmp}" 0
176 ${rm} -f ${tmp}
178 < ${conf} ${sed} -e '/^[ \t]*#/d' -e '/^$/d' -e 's/[ \t]*$//' |
179 while read line; do
180 i=`echo ${line} | ${sed} -e 's/=.*$//'`
181 eval j=\$${i} jx=\${${i}+x}
182 if [ -n "${j}" ] || [ "${jx}" = x ]; then
183 line="${i}=\"${j}\""
185 echo ${line}
186 done > ${tmp}
187 . ./${tmp}
189 wantfeat() {
190 eval i=\$WANT_${1}
191 [ "${i}" = "1" ]
193 nwantfeat() {
194 eval i=\$WANT_${1}
195 [ "${i}" != "1" ]
198 option_update
200 # (No function since some shells loose non-exported variables in traps)
201 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}; exit" 1 2 15
202 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}" 0
203 ${rm} -f ${newlst} ${newmk} ${newh}
205 while read line; do
206 i=`echo ${line} | ${sed} -e 's/=.*$//'`
207 eval j=\$${i}
208 if [ -z "${j}" ] || [ "${j}" = 0 ]; then
209 printf "/*#define ${i}*/\n" >> ${newh}
210 elif [ "${j}" = 1 ]; then
211 printf "#define ${i}\n" >> ${newh}
212 else
213 printf "#define ${i} \"${j}\"\n" >> ${newh}
215 printf "${i} = ${j}\n" >> ${newmk}
216 printf "${i}=\"${j}\"\n"
217 done < ${tmp} > ${newlst}
218 . ./${newlst}
220 printf "#define UAGENT \"${SID}${NAIL}\"\n" >> ${newh}
221 printf "UAGENT = ${SID}${NAIL}\n" >> ${newmk}
223 compiler_flags
225 printf "CC = ${CC}\n" >> ${newmk}
226 printf "_CFLAGS = ${_CFLAGS}\nCFLAGS = ${CFLAGS}\n" >> ${newmk}
227 printf "_LDFLAGS = ${_LDFLAGS}\nLDFLAGS = ${LDFLAGS}\n" >> ${newmk}
228 printf "CMP=${cmp}\nCHMOD=${chmod}\nCP=${cp}\nMKDIR=${mkdir}\nRM=${rm}\n"\
229 >> ${newmk}
230 printf "STRIP=${STRIP}\nHAVE_STRIP=${HAVE_STRIP}\n" >> ${newmk}
231 # (We include the cc(1)/ld(1) environment only for update detection..)
232 printf "CC=\"${CC}\"\n" >> ${newlst}
233 printf "_CFLAGS=\"${_CFLAGS}\"\nCFLAGS=\"${CFLAGS}\"\n" >> ${newlst}
234 printf "_LDFLAGS=\"${_LDFLAGS}\"\nLDFLAGS=\"${LDFLAGS}\"\n" >> ${newlst}
235 printf "CMP=${cmp}\nCHMOD=${chmod}\nCP=${cp}\nMKDIR=${mkdir}\nRM=${rm}\n"\
236 >> ${newlst}
237 printf "STRIP=${STRIP}\nHAVE_STRIP=${HAVE_STRIP}\n" >> ${newlst}
239 if [ -f ${lst} ] && ${cmp} ${newlst} ${lst} >/dev/null 2>&1; then
240 exit 0
242 [ -f ${lst} ] && echo 'configuration updated..' || echo 'shiny configuration..'
244 ${mv} -f ${newlst} ${lst}
245 ${mv} -f ${newh} ${h}
246 ${mv} -f ${newmk} ${mk}
248 ## Compile and link checking ##
250 tmp2=./${tmp0}2$$
251 tmp3=./${tmp0}3$$
252 log=./config.log
253 lib=./config.lib
254 inc=./config.inc
255 src=./config.c
256 makefile=./config.mk
258 # (No function since some shells loose non-exported variables in traps)
259 trap "${rm} -f ${lst} ${h} ${mk} ${lib} ${inc} ${src} ${makefile}; exit" 1 2 15
260 trap "${rm} -rf ${tmp0}.* ${tmp0}* ${makefile}" 0
262 exec 5>&2 > ${log} 2>&1
263 printf '' > ${lib}
264 printf '' > ${inc}
265 # ${src} is only created if WANT_AMALGAMATION
266 ${rm} -f ${src}
267 ${cat} > ${makefile} << \!
268 .SUFFIXES: .o .c .x .y
269 .c.o:
270 $(CC) $(XINCS) -c $<
271 .c.x:
272 $(CC) $(XINCS) -E $< >$@
274 $(CC) $(XINCS) -o $@ $< $(XLIBS)
275 .y: ;
278 msg() {
279 fmt=$1
281 shift
282 printf "*** ${fmt}\\n" "${@}"
283 printf "${fmt}" "${@}" >&5
286 _check_preface() {
287 variable=$1 topic=$2 define=$3
289 echo '**********'
290 msg "checking ${topic} ... "
291 echo "/* checked ${topic} */" >> ${h}
292 ${rm} -f ${tmp} ${tmp}.o
293 echo '*** test program is'
294 ${tee} ${tmp}.c
295 #echo '*** the preprocessor generates'
296 #${make} -f ${makefile} ${tmp}.x
297 #${cat} ${tmp}.x
298 echo '*** results are'
301 compile_check() {
302 variable=$1 topic=$2 define=$3
304 _check_preface "${variable}" "${topic}" "${define}"
306 if ${make} -f ${makefile} XINCS="${INCS}" ./${tmp}.o &&
307 [ -f ./${tmp}.o ]; then
308 msg "yes\\n"
309 echo "${define}" >> ${h}
310 eval have_${variable}=yes
311 return 0
312 else
313 echo "/* ${define} */" >> ${h}
314 msg "no\\n"
315 eval unset have_${variable}
316 return 1
320 _link_mayrun() {
321 run=$1 variable=$2 topic=$3 define=$4 libs=$5 incs=$6
323 _check_preface "${variable}" "${topic}" "${define}"
325 if ${make} -f ${makefile} XINCS="${INCS} ${incs}" \
326 XLIBS="${LIBS} ${libs}" ./${tmp} &&
327 [ -f ./${tmp} ] &&
328 { [ ${run} -eq 0 ] || ./${tmp}; }; then
329 echo "*** adding INCS<${incs}> LIBS<${libs}>"
330 msg "yes\\n"
331 echo "${define}" >> ${h}
332 LIBS="${LIBS} ${libs}"
333 echo "${libs}" >> ${lib}
334 INCS="${INCS} ${incs}"
335 echo "${incs}" >> ${inc}
336 eval have_${variable}=yes
337 return 0
338 else
339 msg "no\\n"
340 echo "/* ${define} */" >> ${h}
341 eval unset have_${variable}
342 return 1
346 link_check() {
347 _link_mayrun 0 "${1}" "${2}" "${3}" "${4}" "${5}"
350 run_check() {
351 _link_mayrun 1 "${1}" "${2}" "${3}" "${4}" "${5}"
354 # Build a basic set of INCS and LIBS according to user environment.
355 # On pkgsrc(7) systems automatically add /usr/pkg/*
356 if [ -n "${C_INCLUDE_PATH}" ]; then
357 i=${IFS}
358 IFS=:
359 set -- ${C_INCLUDE_PATH}
360 IFS=${i}
361 # for i; do -- new in POSIX Issue 7 + TC1
362 for i
364 [ "${i}" = '/usr/pkg/include' ] && continue
365 INCS="${INCS} -I${i}"
366 done
368 [ -d /usr/pkg/include ] && INCS="${INCS} -I/usr/pkg/include"
369 echo "${INCS}" >> ${inc}
371 if [ -n "${LD_LIBRARY_PATH}" ]; then
372 i=${IFS}
373 IFS=:
374 set -- ${LD_LIBRARY_PATH}
375 IFS=${i}
376 # for i; do -- new in POSIX Issue 7 + TC1
377 for i
379 [ "${i}" = '/usr/pkg/lib' ] && continue
380 LIBS="${LIBS} -L${i}"
381 done
383 [ -d /usr/pkg/lib ] && LIBS="${LIBS} -L/usr/pkg/lib"
384 echo "${LIBS}" >> ${lib}
388 # Better set _GNU_SOURCE (if we are on Linux only?)
389 # Fixes compilation on Slackware 14 + (with at least clang(1)).
390 # Since i've always defined this on GNU/Linux, i'm even surprised it works
391 # without!! Didn't check this yet (and TinyCore uses different environment).
392 echo '#define _GNU_SOURCE' >> ${h}
394 link_check hello 'if a hello world program can be built' << \! || {\
395 echo >&5 'This oooops is most certainly not related to me.';\
396 echo >&5 "Read the file ${log} and check your compiler environment.";\
397 ${rm} -f ${lst} ${h} ${mk};\
398 exit 1;\
400 #include <stdio.h>
402 int main(int argc, char *argv[])
404 (void)argc;
405 (void)argv;
406 puts("hello world");
407 return 0;
411 link_check termios 'for termios.h and tc*() family' << \! || {\
412 echo >&5 'We require termios.h and the tc*() family of functions.';\
413 echo >&5 "That much Unix we indulge ourselfs.";\
414 ${rm} -f ${lst} ${h} ${mk};\
415 exit 1;\
417 #include <termios.h>
418 int main(void)
420 struct termios tios;
421 tcgetattr(0, &tios);
422 tcsetattr(0, TCSADRAIN | TCSAFLUSH, &tios);
423 return 0;
427 link_check snprintf 'for snprintf()' '#define HAVE_SNPRINTF' << \!
428 #include <stdio.h>
429 int main(void)
431 char b[20];
432 snprintf(b, sizeof b, "%s", "string");
433 return 0;
437 link_check putc_unlocked 'for putc_unlocked()' '#define HAVE_PUTC_UNLOCKED' <<\!
438 #include <stdio.h>
439 int main(void)
441 putc_unlocked('@', stdout);
442 return 0;
446 link_check fchdir 'for fchdir()' '#define HAVE_FCHDIR' << \!
447 #include <unistd.h>
448 int main(void)
450 fchdir(0);
451 return 0;
455 link_check mmap 'for mmap()' '#define HAVE_MMAP' << \!
456 #include <sys/types.h>
457 #include <sys/mman.h>
458 int main(void)
460 mmap(0, 0, 0, 0, 0, 0);
461 return 0;
465 link_check mremap 'for mremap()' '#define HAVE_MREMAP' << \!
466 #include <sys/types.h>
467 #include <sys/mman.h>
468 int main(void)
470 mremap(0, 0, 0, MREMAP_MAYMOVE);
471 return 0;
475 link_check setlocale 'for setlocale()' '#define HAVE_SETLOCALE' << \!
476 #include <locale.h>
477 int main(void)
479 setlocale(LC_ALL, "");
480 return 0;
484 if [ "${have_setlocale}" = yes ]; then
485 link_check c90amend1 'for ISO/IEC 9899:1990/Amendment 1:1995' \
486 '#define HAVE_C90AMEND1' << \!
487 #include <limits.h>
488 #include <stdlib.h>
489 #include <wchar.h>
490 #include <wctype.h>
491 int main(void)
493 char mbb[MB_LEN_MAX + 1];
494 wchar_t wc;
495 iswprint(L'c');
496 towupper(L'c');
497 mbtowc(&wc, "x", 1);
498 mbrtowc(&wc, "x", 1, NULL);
499 (void)wctomb(mbb, wc);
500 return (mblen("\0", 1) == 0);
504 if [ "${have_c90amend1}" = yes ]; then
505 link_check wcwidth 'for wcwidth()' '#define HAVE_WCWIDTH' << \!
506 #include <wchar.h>
507 int main(void)
509 wcwidth(L'c');
510 return 0;
515 link_check nl_langinfo 'for nl_langinfo()' '#define HAVE_NL_LANGINFO' << \!
516 #include <langinfo.h>
517 #include <stdlib.h>
518 int main(void)
520 nl_langinfo(DAY_1);
521 return (nl_langinfo(CODESET) == NULL);
524 fi # have_setlocale
526 link_check mkstemp 'for mkstemp()' '#define HAVE_MKSTEMP' << \!
527 #include <stdlib.h>
528 int main(void)
530 mkstemp("x");
531 return 0;
535 # Note: run_check, thus we also get only the desired implementation...
536 run_check realpath 'for realpath()' '#define HAVE_REALPATH' << \!
537 #include <stdlib.h>
538 int main(void)
540 char *x = realpath(".", NULL), *y = realpath("/", NULL);
541 return (x != NULL && y != NULL) ? 0 : 1;
545 link_check wordexp 'for wordexp()' '#define HAVE_WORDEXP' << \!
546 #include <wordexp.h>
547 int main(void)
549 wordexp((char *)0, (wordexp_t *)0, 0);
550 return 0;
556 if wantfeat DEBUG; then
557 echo '#define HAVE_DEBUG' >> ${h}
560 if wantfeat AMALGAMATION; then
561 echo '#define HAVE_AMALGAMATION' >> ${h}
564 if nwantfeat NOALLOCA; then
565 # Due to NetBSD PR lib/47120 it seems best not to use non-cc-builtin
566 # versions of alloca(3) since modern compilers just can't be trusted
567 # not to overoptimize and silently break some code
568 link_check alloca 'for __builtin_alloca()' \
569 '#define HAVE_ALLOCA __builtin_alloca' << \!
570 int main(void)
572 void *vp = __builtin_alloca(1);
573 return (!! vp);
578 if nwantfeat NOGETOPT; then
579 link_check getopt 'for getopt()' '#define HAVE_GETOPT' << \!
580 #include <unistd.h>
581 int main(int argc, char **argv)
583 #if defined __GLIBC__ || defined __linux__
584 Argument and option reordering is not a desired feature.
585 #else
586 getopt(argc, argv, "oPt");
587 #endif
588 return (((long)optarg + optind) & 0x7F);
595 if wantfeat ICONV; then
596 ${cat} > ${tmp2}.c << \!
597 #include <iconv.h>
598 int main(void)
600 iconv_t id;
602 id = iconv_open("foo", "bar");
603 return 0;
606 < ${tmp2}.c link_check iconv 'for iconv functionality' \
607 '#define HAVE_ICONV' ||
608 < ${tmp2}.c link_check iconv \
609 'for iconv functionality in libiconv' \
610 '#define HAVE_ICONV' '-liconv'
611 else
612 echo '/* WANT_ICONV=0 */' >> ${h}
613 fi # wantfeat ICONV
615 if wantfeat SOCKETS; then
616 compile_check arpa_inet_h 'for <arpa/inet.h>' \
617 '#define HAVE_ARPA_INET_H' << \!
618 #include "config.h"
619 #include <sys/types.h>
620 #include <sys/socket.h>
621 #include <netdb.h>
622 #include <netinet/in.h>
623 #include <arpa/inet.h>
626 ${cat} > ${tmp2}.c << \!
627 #include "config.h"
628 #include <sys/types.h>
629 #include <sys/socket.h>
630 #include <netdb.h>
631 #include <netinet/in.h>
632 #ifdef HAVE_ARPA_INET_H
633 #include <arpa/inet.h>
634 #endif
636 int main(void)
638 struct sockaddr s;
639 socket(AF_INET, SOCK_STREAM, 0);
640 connect(0, &s, 0);
641 gethostbyname("foo");
642 return 0;
646 < ${tmp2}.c link_check sockets 'for sockets in libc' \
647 '#define HAVE_SOCKETS' ||
648 < ${tmp2}.c link_check sockets 'for sockets in libnsl' \
649 '#define HAVE_SOCKETS' '-lnsl' ||
650 < ${tmp2}.c link_check sockets \
651 'for sockets in libsocket and libnsl' \
652 '#define HAVE_SOCKETS' '-lsocket -lnsl' ||
653 WANT_SOCKETS=0
655 # XXX Shouldn't it be a hard error if there is no socket support, then?
656 option_update
657 else
658 echo '/* WANT_SOCKETS=0 */' >> ${h}
659 fi # wantfeat SOCKETS
661 wantfeat SOCKETS &&
662 link_check setsockopt 'for setsockopt()' '#define HAVE_SETSOCKOPT' << \!
663 #include <sys/socket.h>
664 #include <stdlib.h>
665 int main(void)
667 int sockfd = 3;
668 setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0);
669 return 0;
673 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
674 link_check so_sndtimeo 'for SO_SNDTIMEO' '#define HAVE_SO_SNDTIMEO' << \!
675 #include <sys/socket.h>
676 #include <stdlib.h>
677 int main(void)
679 struct timeval tv;
680 int sockfd = 3;
681 tv.tv_sec = 42;
682 tv.tv_usec = 21;
683 setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
684 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
685 return 0;
689 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
690 link_check so_linger 'for SO_LINGER' '#define HAVE_SO_LINGER' << \!
691 #include <sys/socket.h>
692 #include <stdlib.h>
693 int main(void)
695 struct linger li;
696 int sockfd = 3;
697 li.l_onoff = 1;
698 li.l_linger = 42;
699 setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &li, sizeof li);
700 return 0;
704 if wantfeat IPV6; then
705 link_check ipv6 'for IPv6 functionality' '#define HAVE_IPV6' << \!
706 #include "config.h"
707 #include <sys/types.h>
708 #include <sys/socket.h>
709 #include <netdb.h>
710 #include <netinet/in.h>
711 #ifdef HAVE_ARPA_INET_H
712 #include <arpa/inet.h>
713 #endif
715 int main(void)
717 struct addrinfo a, *ap;
718 getaddrinfo("foo", "0", &a, &ap);
719 return 0;
722 else
723 echo '/* WANT_IPV6=0 */' >> ${h}
724 fi # wantfeat IPV6
726 if wantfeat IMAP; then
727 echo '#define HAVE_IMAP' >> ${h}
728 else
729 echo '/* WANT_IMAP=0 */' >> ${h}
732 if wantfeat POP3; then
733 echo '#define HAVE_POP3' >> ${h}
734 else
735 echo '/* WANT_POP3=0 */' >> ${h}
738 if wantfeat SMTP; then
739 echo '#define HAVE_SMTP' >> ${h}
740 else
741 echo '/* WANT_SMTP=0 */' >> ${h}
744 if wantfeat SSL; then
745 link_check openssl 'for sufficiently recent OpenSSL' \
746 '#define HAVE_SSL
747 #define HAVE_OPENSSL' '-lssl -lcrypto' << \!
748 #include <openssl/ssl.h>
749 #include <openssl/err.h>
750 #include <openssl/x509v3.h>
751 #include <openssl/x509.h>
752 #include <openssl/rand.h>
754 #if defined OPENSSL_NO_SSL2 && defined OPENSSL_NO_SSL3 &&\
755 defined OPENSSL_NO_TLS1
756 # error We need one of (SSLv2 and) SSLv3 and TLS1.
757 #endif
759 int main(void)
761 SSLv23_client_method();
762 #ifndef OPENSSL_NO_SSL3
763 SSLv3_client_method();
764 #endif
765 #ifndef OPENSSL_NO_TLS1
766 TLSv1_client_method();
767 # ifdef TLS1_1_VERSION
768 TLSv1_1_client_method();
769 # endif
770 # ifdef TLS1_2_VERSION
771 TLSv1_2_client_method();
772 # endif
773 #endif
774 PEM_read_PrivateKey(0, 0, 0, 0);
775 return 0;
779 if [ "${have_openssl}" = 'yes' ]; then
780 compile_check stack_of 'for OpenSSL STACK_OF()' \
781 '#define HAVE_STACK_OF' << \!
782 #include <openssl/ssl.h>
783 #include <openssl/err.h>
784 #include <openssl/x509v3.h>
785 #include <openssl/x509.h>
786 #include <openssl/rand.h>
788 int main(void)
790 STACK_OF(GENERAL_NAME) *gens = NULL;
791 printf("%p", gens); /* to make it used */
792 return 0;
796 run_check openssl_md5 'for MD5 digest in OpenSSL' \
797 '#define HAVE_OPENSSL_MD5' << \!
798 #include <string.h>
799 #include <openssl/md5.h>
801 int main(void)
803 char const dat[] = "abrakadabrafidibus";
804 char dig[16], hex[16 * 2];
805 MD5_CTX ctx;
806 size_t i, j;
808 memset(dig, 0, sizeof(dig));
809 memset(hex, 0, sizeof(hex));
810 MD5_Init(&ctx);
811 MD5_Update(&ctx, dat, sizeof(dat) - 1);
812 MD5_Final(dig, &ctx);
814 #define hexchar(n) ((n)>9 ? (n)-10+'a' : (n)+'0')
815 for (i = 0; i < sizeof(hex) / 2; i++) {
816 j = i << 1;
817 hex[j] = hexchar((dig[i] & 0xf0) >> 4);
818 hex[++j] = hexchar(dig[i] & 0x0f);
820 return !!memcmp("6d7d0a3d949da2e96f2aa010f65d8326", hex, sizeof(hex));
825 else
826 echo '/* WANT_SSL=0 */' >> ${h}
827 fi # wantfeat SSL
829 if wantfeat GSSAPI; then
830 ${cat} > ${tmp2}.c << \!
831 #include <gssapi/gssapi.h>
833 int main(void)
835 gss_import_name(0, 0, GSS_C_NT_HOSTBASED_SERVICE, 0);
836 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
837 return 0;
840 ${sed} -e '1s/gssapi\///' < ${tmp2}.c > ${tmp3}.c
842 if command -v krb5-config >/dev/null 2>&1; then
843 i=`command -v krb5-config`
844 GSSAPI_LIBS="`CFLAGS= ${i} --libs gssapi`"
845 GSSAPI_INCS="`CFLAGS= ${i} --cflags`"
846 i='for GSSAPI via krb5-config(1)'
847 else
848 GSSAPI_LIBS='-lgssapi'
849 GSSAPI_INCS=
850 i='for GSSAPI in gssapi/gssapi.h, libgssapi'
852 < ${tmp2}.c link_check gssapi \
853 "${i}" '#define HAVE_GSSAPI' \
854 "${GSSAPI_LIBS}" "${GSSAPI_INCS}" ||\
855 < ${tmp3}.c link_check gssapi \
856 'for GSSAPI in gssapi.h, libgssapi' \
857 '#define HAVE_GSSAPI
858 #define GSSAPI_REG_INCLUDE' \
859 '-lgssapi' ||\
860 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgssapi_krb5' \
861 '#define HAVE_GSSAPI' \
862 '-lgssapi_krb5' ||\
863 < ${tmp3}.c link_check gssapi \
864 'for GSSAPI in libgssapi, OpenBSD-style (pre 5.3)' \
865 '#define HAVE_GSSAPI
866 #define GSSAPI_REG_INCLUDE' \
867 '-lgssapi -lkrb5 -lcrypto' \
868 '-I/usr/include/kerberosV' ||\
869 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgss' \
870 '#define HAVE_GSSAPI' \
871 '-lgss' ||\
872 link_check gssapi 'for GSSAPI in libgssapi_krb5, old-style' \
873 '#define HAVE_GSSAPI
874 #define GSSAPI_OLD_STYLE' \
875 '-lgssapi_krb5' << \!
876 #include <gssapi/gssapi.h>
877 #include <gssapi/gssapi_generic.h>
879 int main(void)
881 gss_import_name(0, 0, gss_nt_service_name, 0);
882 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
883 return 0;
886 else
887 echo '/* WANT_GSSAPI=0 */' >> ${h}
888 fi # wantfeat GSSAPI
890 if wantfeat IDNA; then
891 link_check idna 'for GNU Libidn' '#define HAVE_IDNA' '-lidn' << \!
892 #include <idna.h>
893 #include <stringprep.h>
894 int main(void)
896 char *utf8, *idna_ascii, *idna_utf8;
897 utf8 = stringprep_locale_to_utf8("does.this.work");
898 if (idna_to_ascii_8z(utf8, &idna_ascii, IDNA_USE_STD3_ASCII_RULES)
899 != IDNA_SUCCESS)
900 return 1;
901 /* (Rather link check only here) */
902 idna_utf8 = stringprep_convert(idna_ascii, "UTF-8", "de_DE");
903 return 0;
906 else
907 echo '/* WANT_IDNA=0 */' >> ${h}
908 fi # wantfeat IDNA
910 if wantfeat READLINE; then
911 __edrdlib() {
912 link_check readline "for readline(3) (${1})" \
913 '#define HAVE_READLINE' "${1}" << \!
914 #include <stdio.h>
915 #include <readline/history.h>
916 #include <readline/readline.h>
917 int main(void)
919 char *rl;
920 using_history();
921 read_history("");
922 stifle_history(242);
923 rl = readline("Enter a line:");
924 if (rl && *rl)
925 add_history(rl);
926 write_history("");
927 rl_extend_line_buffer(10);
928 rl_point = rl_end = 10;
929 rl_pre_input_hook = (rl_hook_func_t*)NULL;
930 rl_forced_update_display();
932 rl_free_line_state();
933 rl_cleanup_after_signal();
934 rl_reset_after_signal();
935 return 0;
940 __edrdlib -lreadline ||
941 __edrdlib '-lreadline -ltermcap'
942 [ -n "${have_readline}" ] && WANT_TABEXPAND=1
945 if wantfeat EDITLINE && [ -z "${have_readline}" ]; then
946 __edlib() {
947 link_check editline "for editline(3) (${1})" \
948 '#define HAVE_EDITLINE' "${1}" << \!
949 #include <histedit.h>
950 static char * getprompt(void) { return (char*)"ok"; }
951 int main(void)
953 HistEvent he;
954 EditLine *el_el = el_init("TEST", stdin, stdout, stderr);
955 History *el_hcom = history_init();
956 history(el_hcom, &he, H_SETSIZE, 242);
957 el_set(el_el, EL_SIGNAL, 0);
958 el_set(el_el, EL_TERMINAL, NULL);
959 el_set(el_el, EL_HIST, &history, el_hcom);
960 el_set(el_el, EL_EDITOR, "emacs");
961 el_set(el_el, EL_PROMPT, &getprompt);
962 el_source(el_el, NULL);
963 el_end(el_el);
964 /* TODO add loader and addfn checks */
965 history_end(el_hcom);
966 return 0;
971 __edlib -ledit ||
972 __edlib '-ledit -ltermcap'
973 [ -n "${have_editline}" ] && WANT_TABEXPAND=0
976 if wantfeat NCL && [ -z "${have_editline}" ] && [ -z "${have_readline}" ] &&\
977 [ -n "${have_c90amend1}" ]; then
978 have_ncl=1
979 echo '#define HAVE_NCL' >> ${h}
980 else
981 echo '/* WANT_{READLINE,EDITLINE,NCL}=0 */' >> ${h}
984 if [ -n "${have_ncl}" ] || [ -n "${have_editline}" ] ||\
985 [ -n "${have_readline}" ]; then
986 have_cle=1
989 if [ -n "${have_cle}" ] && wantfeat TABEXPAND; then
990 echo '#define HAVE_TABEXPAND' >> ${h}
991 else
992 echo '/* WANT_TABEXPAND=0 */' >> ${h}
995 if [ -n "${have_cle}" ] && wantfeat HISTORY; then
996 echo '#define HAVE_HISTORY' >> ${h}
997 else
998 echo '/* WANT_HISTORY=0 */' >> ${h}
1001 if wantfeat QUOTE_FOLD &&\
1002 [ -n "${have_c90amend1}" ] && [ -n "${have_wcwidth}" ]; then
1003 echo '#define HAVE_QUOTE_FOLD' >> ${h}
1004 else
1005 echo '/* WANT_QUOTE_FOLD=0 */' >> ${h}
1008 if wantfeat DOCSTRINGS; then
1009 echo '#define HAVE_DOCSTRINGS' >> ${h}
1010 else
1011 echo '/* WANT_DOCSTRINGS=0 */' >> ${h}
1014 if wantfeat SPAM; then
1015 echo '#define HAVE_SPAM' >> ${h}
1016 if command -v spamc >/dev/null 2>&1; then
1017 echo "#define SPAMC_PATH \"`command -v spamc`\"" >> ${h}
1019 else
1020 echo '/* WANT_SPAM=0 */' >> ${h}
1023 if wantfeat MD5; then
1024 echo '#define HAVE_MD5' >> ${h}
1025 else
1026 echo '/* WANT_MD5=0 */' >> ${h}
1029 ## Summarizing ##
1031 # Since we cat(1) the content of those to cc/"ld", convert them to single line
1032 squeeze_em() {
1033 < "${1}" > "${2}" ${awk} \
1034 'BEGIN {ORS = " "} /^[^#]/ {print} {next} END {ORS = ""; print "\n"}'
1036 ${rm} -f ${tmp}
1037 squeeze_em ${inc} ${tmp}
1038 ${mv} ${tmp} ${inc}
1039 squeeze_em ${lib} ${tmp}
1040 ${mv} ${tmp} ${lib}
1042 # config.h
1043 ${mv} ${h} ${tmp}
1044 printf '#ifndef _CONFIG_H\n# define _CONFIG_H\n' > ${h}
1045 ${cat} ${tmp} >> ${h}
1047 printf '\n/* The "feature string", for "simplicity" and lex.c */\n' >> ${h}
1048 printf '#ifdef _MAIN_SOURCE\n' >> ${h}
1049 printf '# ifdef HAVE_AMALGAMATION\nstatic\n# endif\n' >> ${h}
1050 printf 'char const features[] = "MIME"\n' >> ${h}
1051 printf '# ifdef HAVE_DOCSTRINGS\n ",DOCSTRINGS"\n# endif\n' >> ${h}
1052 printf '# ifdef HAVE_ICONV\n ",ICONV"\n# endif\n' >> ${h}
1053 printf '# ifdef HAVE_SETLOCALE\n ",LOCALES"\n# endif\n' >> ${h}
1054 printf '# ifdef HAVE_C90AMEND1\n ",MULTIBYTE CHARSETS"\n# endif\n' >> ${h}
1055 printf '# ifdef HAVE_NL_LANGINFO\n ",TERMINAL CHARSET"\n# endif\n' >> ${h}
1056 printf '# ifdef HAVE_SOCKETS\n ",NETWORK"\n# endif\n' >> ${h}
1057 printf '# ifdef HAVE_IPV6\n ",IPv6"\n# endif\n' >> ${h}
1058 printf '# ifdef HAVE_SSL\n ",S/MIME,SSL/TSL"\n# endif\n' >> ${h}
1059 printf '# ifdef HAVE_IMAP\n ",IMAP"\n# endif\n' >> ${h}
1060 printf '# ifdef HAVE_GSSAPI\n ",GSSAPI"\n# endif\n' >> ${h}
1061 printf '# ifdef HAVE_POP3\n ",POP3"\n# endif\n' >> ${h}
1062 printf '# ifdef HAVE_SMTP\n ",SMTP"\n# endif\n' >> ${h}
1063 printf '# ifdef HAVE_SPAM\n ",SPAM"\n# endif\n' >> ${h}
1064 printf '# ifdef HAVE_IDNA\n ",IDNA"\n# endif\n' >> ${h}
1065 printf '# ifdef HAVE_READLINE\n ",READLINE"\n# endif\n' >> ${h}
1066 printf '# ifdef HAVE_EDITLINE\n ",EDITLINE"\n# endif\n' >> ${h}
1067 printf '# ifdef HAVE_NCL\n ",NCL"\n# endif\n' >> ${h}
1068 printf '# ifdef HAVE_TABEXPAND\n ",TABEXPAND"\n# endif\n' >> ${h}
1069 printf '# ifdef HAVE_HISTORY\n ",HISTORY MANAGEMENT"\n# endif\n' >> ${h}
1070 printf '# ifdef HAVE_QUOTE_FOLD\n ",QUOTE-FOLD"\n# endif\n' >> ${h}
1071 printf '# ifdef HAVE_DEBUG\n ",DEBUG"\n# endif\n' >> ${h}
1072 printf ';\n#endif /* _MAIN_SOURCE */\n' >> ${h}
1074 printf '#endif /* _CONFIG_H */\n' >> ${h}
1075 ${rm} -f ${tmp}
1077 # Create the real mk.mk
1078 ${rm} -rf ${tmp0}.* ${tmp0}*
1079 printf 'OBJ_SRC = ' >> ${mk}
1080 if nwantfeat AMALGAMATION; then
1081 echo *.c >> ${mk}
1082 echo 'OBJ_DEP =' >> ${mk}
1083 else
1084 j=`echo "${src}" | sed 's/^.\///'`
1085 echo "${j}" >> ${mk}
1086 printf 'OBJ_DEP = main.c ' >> ${mk}
1087 printf '#define _MAIN_SOURCE\n' >> ${src}
1088 printf '#include "nail.h"\n#include "main.c"\n' >> ${src}
1089 for i in *.c; do
1090 if [ "${i}" = "${j}" ] || [ "${i}" = main.c ]; then
1091 continue
1093 printf "${i} " >> ${mk}
1094 printf "#include \"${i}\"\n" >> ${src}
1095 done
1096 echo >> ${mk}
1099 echo "LIBS = `${cat} ${lib}`" >> ${mk}
1100 echo "INCLUDES = `${cat} ${inc}`" >> ${mk}
1101 echo >> ${mk}
1102 ${cat} ./mk-mk.in >> ${mk}
1104 ## Finished! ##
1106 ${cat} > ${tmp2}.c << \!
1107 #include "config.h"
1108 #ifdef HAVE_NL_LANGINFO
1109 # include <langinfo.h>
1110 #endif
1112 :The following optional features are enabled:
1113 #ifdef HAVE_ICONV
1114 : + Character set conversion using iconv()
1115 #endif
1116 #ifdef HAVE_SETLOCALE
1117 : + Locale support: Printable characters depend on the environment
1118 # ifdef HAVE_C90AMEND1
1119 : + Multibyte character support
1120 # endif
1121 # ifdef HAVE_NL_LANGINFO
1122 : + Automatic detection of terminal character set
1123 # endif
1124 #endif
1125 #ifdef HAVE_SOCKETS
1126 : + Network support
1127 #endif
1128 #ifdef HAVE_IPV6
1129 : + Support for Internet Protocol v6 (IPv6)
1130 #endif
1131 #ifdef HAVE_SSL
1132 # ifdef HAVE_OPENSSL
1133 : + S/MIME and SSL/TLS using OpenSSL
1134 # endif
1135 #endif
1136 #ifdef HAVE_IMAP
1137 : + IMAP protocol
1138 #endif
1139 #ifdef HAVE_GSSAPI
1140 : + IMAP GSSAPI authentication
1141 #endif
1142 #ifdef HAVE_POP3
1143 : + POP3 protocol
1144 #endif
1145 #ifdef HAVE_SMTP
1146 : + SMTP protocol
1147 #endif
1148 #ifdef HAVE_SPAM
1149 : + Interaction with spam filters
1150 #endif
1151 #ifdef HAVE_IDNA
1152 : + IDNA (internationalized domain names for applications) support
1153 #endif
1154 #if defined HAVE_READLINE || defined HAVE_EDITLINE || defined HAVE_NCL
1155 : + Command line editing
1156 # ifdef HAVE_TABEXPAND
1157 : + + Tabulator expansion
1158 # endif
1159 # ifdef HAVE_HISTORY
1160 : + + History management
1161 # endif
1162 #endif
1163 #ifdef HAVE_QUOTE_FOLD
1164 : + Extended *quote-fold*ing
1165 #endif
1167 :The following optional features are disabled:
1168 #ifndef HAVE_ICONV
1169 : - Character set conversion using iconv()
1170 #endif
1171 #ifndef HAVE_SETLOCALE
1172 : - Locale support: Only ASCII characters are recognized
1173 #endif
1174 # ifndef HAVE_C90AMEND1
1175 : - Multibyte character support
1176 # endif
1177 # ifndef HAVE_NL_LANGINFO
1178 : - Automatic detection of terminal character set
1179 # endif
1180 #ifndef HAVE_SOCKETS
1181 : - Network support
1182 #endif
1183 #ifndef HAVE_IPV6
1184 : - Support for Internet Protocol v6 (IPv6)
1185 #endif
1186 #if !defined HAVE_SSL
1187 : - SSL/TLS (network transport authentication and encryption)
1188 #endif
1189 #ifndef HAVE_IMAP
1190 : - IMAP protocol
1191 #endif
1192 #ifndef HAVE_GSSAPI
1193 : - IMAP GSSAPI authentication
1194 #endif
1195 #ifndef HAVE_POP3
1196 : - POP3 protocol
1197 #endif
1198 #ifndef HAVE_SMTP
1199 : - SMTP protocol
1200 #endif
1201 #ifndef HAVE_SPAM
1202 : - Interaction with spam filters
1203 #endif
1204 #ifndef HAVE_IDNA
1205 : - IDNA (internationalized domain names for applications) support
1206 #endif
1207 #if !defined HAVE_READLINE && !defined HAVE_EDITLINE && !defined HAVE_NCL
1208 : - Command line editing and history
1209 #endif
1210 #ifndef HAVE_QUOTE_FOLD
1211 : - Extended *quote-fold*ing
1212 #endif
1214 :Remarks:
1215 #ifndef HAVE_SNPRINTF
1216 : . The function snprintf() could not be found. mailx will be compiled to use
1217 : sprintf() instead. This might overflow buffers if input values are larger
1218 : than expected. Use the resulting binary with care or update your system
1219 : environment and start the configuration process again.
1220 #endif
1221 #ifndef HAVE_FCHDIR
1222 : . The function fchdir() could not be found. mailx will be compiled to use
1223 : chdir() instead. This is not a problem unless the current working
1224 : directory of mailx is moved while the IMAP cache is used.
1225 #endif
1226 #ifndef HAVE_GETOPT
1227 : . Using a minimal builtin POSIX-like getopt()
1228 #endif
1229 #ifdef HAVE_DEBUG
1230 : . Debug enabled binary: not meant to be used by end-users: THANKS!
1231 #endif
1235 ${make} -f ${makefile} ${tmp2}.x
1236 < ${tmp2}.x >&5 ${sed} -e '/^[^:]/d; /^$/d; s/^://'
1238 # vim:set fenc=utf-8:s-it-mode