INSTALL: update for v14.5.1
[s-mailx.git] / mk-conf.sh
bloba1ffec3e45add2d3d134fb30878e8046919464f6
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_REGEX=0
31 WANT_SPAM=0
32 WANT_DOCSTRINGS=0
33 WANT_QUOTE_FOLD=0
35 MEDIUM)
36 WANT_SOCKETS=0
37 WANT_IDNA=0
38 WANT_READLINE=0 WANT_EDITLINE=0
39 WANT_REGEX=0
40 WANT_SPAM=0
41 WANT_QUOTE_FOLD=0
43 NETSEND)
44 WANT_IMAP=0
45 WANT_POP3=0
46 WANT_READLINE=0 WANT_EDITLINE=0
47 WANT_REGEX=0
48 WANT_SPAM=0
49 WANT_QUOTE_FOLD=0
52 echo >&2 "Unknown CONFIG= setting: ${CONFIG}"
53 echo >&2 'Possible values: MINIMAL, MEDIUM, NETSEND'
54 exit 1
55 esac
58 # Inter-relationships
59 option_update() {
60 if nwantfeat SOCKETS; then
61 WANT_IPV6=0 WANT_SSL=0
62 WANT_IMAP=0 WANT_GSSAPI=0 WANT_POP3=0 WANT_SMTP=0
64 if nwantfeat IMAP && nwantfeat POP3 && nwantfeat SMTP; then
65 WANT_SOCKETS=0 WANT_IPV6=0 WANT_SSL=0
67 if nwantfeat IMAP; then
68 WANT_GSSAPI=0
70 # If we don't need MD5 except for producing boundary and message-id strings,
71 # leave it off, plain old srand(3) should be enough for that purpose.
72 if nwantfeat SOCKETS; then
73 WANT_MD5=0
75 if wantfeat DEBUG; then
76 WANT_NOALLOCA=1
80 # Check out compiler ($CC) and -flags ($CFLAGS)
81 compiler_flags() {
82 i=`uname -s`
83 _CFLAGS=
85 # $CC is overwritten when empty or a default "cc", even without WANT_AUTOCC
86 if [ -z "${CC}" ] || [ "${CC}" = cc ]; then
87 _CFLAGS=
88 if { CC="`command -v clang`"; }; then
90 elif { CC="`command -v gcc`"; }; then
92 elif { CC="`command -v c89`"; }; then
93 [ "${i}" = UnixWare ] && _CFLAGS='-v -O'
94 elif { CC="`command -v c99`"; }; then
96 else
97 echo >&2 'ERROR'
98 echo >&2 ' I cannot find a compiler!'
99 echo >&2 ' Neither of clang(1), gcc(1), c89(1) and c99(1).'
100 echo >&2 ' Please set the CC environment variable, maybe CFLAGS also.'
101 exit 1
104 export CC
106 ccver=`${CC} --version 2>/dev/null`
107 stackprot=no
108 if { i=$ccver; echo "${i}"; } | ${grep} -q -i -e gcc -e clang; then
109 #if echo "${i}" | ${grep} -q -i -e gcc -e 'clang version 1'; then
110 stackprot=yes
111 _CFLAGS='-std=c89 -O2'
112 _CFLAGS="${_CFLAGS} -Wall -Wextra -pedantic"
113 _CFLAGS="${_CFLAGS} -fno-unwind-tables -fno-asynchronous-unwind-tables"
114 _CFLAGS="${_CFLAGS} -fstrict-aliasing"
115 _CFLAGS="${_CFLAGS} -Wbad-function-cast -Wcast-align -Wcast-qual"
116 _CFLAGS="${_CFLAGS} -Winit-self -Wshadow -Wunused -Wwrite-strings"
117 if { i=$ccver; echo "${i}"; } | ${grep} -q -e 'clang version 1'; then
119 else
120 _CFLAGS="${_CFLAGS} -fstrict-overflow -Wstrict-overflow=5"
121 if wantfeat AMALGAMATION && nwantfeat DEBUG; then
122 _CFLAGS="${_CFLAGS} -Wno-unused-function"
124 if { i=$ccver; echo "${i}"; } | ${grep} -q -i -e clang; then
125 _CFLAGS="${_CFLAGS} -Wno-unused-result" # TODO handle the right way
128 _CFLAGS="${_CFLAGS} -Wno-long-long" # ISO C89 has no 'long long'...
129 # elif { i=$ccver; echo "${i}"; } | ${grep} -q -i -e clang; then
130 # stackprot=yes
131 # _CFLAGS='-std=c89 -O3 -g -Weverything -Wno-long-long'
132 elif [ -z "${_CFLAGS}" ]; then
133 _CFLAGS=-O1
136 if nwantfeat DEBUG; then
137 _CFLAGS="${_CFLAGS} -DNDEBUG"
138 else
139 _CFLAGS="${_CFLAGS} -g";
140 if [ "${stackprot}" = yes ]; then
141 _CFLAGS="${_CFLAGS} -fstack-protector-all "
142 _CFLAGS="${_CFLAGS} -Wstack-protector -D_FORTIFY_SOURCE=2"
145 _CFLAGS="${_CFLAGS} ${ADDCFLAGS}"
146 _LDFLAGS="${_LDFLAGS} ${ADDLDFLAGS}" # XXX -Wl,--sort-common,[-O1]
147 export _CFLAGS _LDFLAGS
149 # $CFLAGS and $LDFLAGS are only overwritten if explicitly wanted
150 if wantfeat AUTOCC; then
151 CFLAGS=$_CFLAGS
152 LDFLAGS=$_LDFLAGS
153 export CFLAGS LDFLAGS
157 ## -- >8 -- 8< -- ##
159 ## Notes:
160 ## - Heirloom sh(1) (and same origin) have problems with ': >' redirection,
161 ## so use "printf '' >" instead
162 ## - Heirloom sh(1) and maybe more execute loops with redirection in a subshell
163 ## (but don't export eval's from within), therefore we need to (re)include
164 ## variable assignments at toplevel instead (via reading temporary files)
166 ## First of all, create new configuration and check wether it changed ##
168 conf=./conf.rc
169 lst=./config.lst
170 h=./config.h
171 mk=./mk.mk
173 newlst=./config.lst-new
174 newmk=./config.mk-new
175 newh=./config.h-new
176 tmp0=___tmp
177 tmp=./${tmp0}1$$
179 # Only incorporate what wasn't overwritten from command line / CONFIG
180 trap "${rm} -f ${tmp}; exit" 1 2 15
181 trap "${rm} -f ${tmp}" 0
182 ${rm} -f ${tmp}
184 < ${conf} ${sed} -e '/^[ \t]*#/d' -e '/^$/d' -e 's/[ \t]*$//' |
185 while read line; do
186 i=`echo ${line} | ${sed} -e 's/=.*$//'`
187 eval j=\$${i} jx=\${${i}+x}
188 if [ -n "${j}" ] || [ "${jx}" = x ]; then
189 line="${i}=\"${j}\""
191 echo ${line}
192 done > ${tmp}
193 . ./${tmp}
195 wantfeat() {
196 eval i=\$WANT_${1}
197 [ "${i}" = "1" ]
199 nwantfeat() {
200 eval i=\$WANT_${1}
201 [ "${i}" != "1" ]
204 option_update
206 # (No function since some shells loose non-exported variables in traps)
207 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}; exit" 1 2 15
208 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}" 0
209 ${rm} -f ${newlst} ${newmk} ${newh}
211 # (Could: use FD redirection, add eval(1) and don't re-'. ./${newlst}')
212 while read line; do
213 i=`echo ${line} | ${sed} -e 's/=.*$//'`
214 eval j=\$${i}
215 if [ -z "${j}" ] || [ "${j}" = 0 ]; then
216 printf "/*#define ${i}*/\n" >> ${newh}
217 elif [ "${j}" = 1 ]; then
218 printf "#define ${i}\n" >> ${newh}
219 else
220 printf "#define ${i} \"${j}\"\n" >> ${newh}
222 printf "${i} = ${j}\n" >> ${newmk}
223 printf "${i}=\"${j}\"\n"
224 done < ${tmp} > ${newlst}
225 . ./${newlst}
227 printf "#define UAGENT \"${SID}${NAIL}\"\n" >> ${newh}
228 printf "UAGENT = ${SID}${NAIL}\n" >> ${newmk}
230 compiler_flags
232 printf "CC = ${CC}\n" >> ${newmk}
233 printf "_CFLAGS = ${_CFLAGS}\nCFLAGS = ${CFLAGS}\n" >> ${newmk}
234 printf "_LDFLAGS = ${_LDFLAGS}\nLDFLAGS = ${LDFLAGS}\n" >> ${newmk}
235 printf "CMP=${cmp}\nCHMOD=${chmod}\nCP=${cp}\nMKDIR=${mkdir}\nRM=${rm}\n"\
236 >> ${newmk}
237 printf "STRIP=${STRIP}\nHAVE_STRIP=${HAVE_STRIP}\n" >> ${newmk}
238 # (We include the cc(1)/ld(1) environment only for update detection..)
239 printf "CC=\"${CC}\"\n" >> ${newlst}
240 printf "_CFLAGS=\"${_CFLAGS}\"\nCFLAGS=\"${CFLAGS}\"\n" >> ${newlst}
241 printf "_LDFLAGS=\"${_LDFLAGS}\"\nLDFLAGS=\"${LDFLAGS}\"\n" >> ${newlst}
242 printf "CMP=${cmp}\nCHMOD=${chmod}\nCP=${cp}\nMKDIR=${mkdir}\nRM=${rm}\n"\
243 >> ${newlst}
244 printf "STRIP=${STRIP}\nHAVE_STRIP=${HAVE_STRIP}\n" >> ${newlst}
246 if [ -f ${lst} ] && ${cmp} ${newlst} ${lst} >/dev/null 2>&1; then
247 exit 0
249 [ -f ${lst} ] && echo 'configuration updated..' || echo 'shiny configuration..'
251 ${mv} -f ${newlst} ${lst}
252 ${mv} -f ${newh} ${h}
253 ${mv} -f ${newmk} ${mk}
255 ## Compile and link checking ##
257 tmp2=./${tmp0}2$$
258 tmp3=./${tmp0}3$$
259 log=./config.log
260 lib=./config.lib
261 inc=./config.inc
262 src=./config.c
263 makefile=./config.mk
265 # (No function since some shells loose non-exported variables in traps)
266 trap "${rm} -f ${lst} ${h} ${mk} ${lib} ${inc} ${src} ${makefile}; exit" 1 2 15
267 trap "${rm} -rf ${tmp0}.* ${tmp0}* ${makefile}" 0
269 exec 5>&2 > ${log} 2>&1
270 printf '' > ${lib}
271 printf '' > ${inc}
272 # ${src} is only created if WANT_AMALGAMATION
273 ${rm} -f ${src}
274 ${cat} > ${makefile} << \!
275 .SUFFIXES: .o .c .x .y
276 .c.o:
277 $(CC) $(XINCS) -c $<
278 .c.x:
279 $(CC) $(XINCS) -E $< >$@
281 $(CC) $(XINCS) -o $@ $< $(XLIBS)
282 .y: ;
285 msg() {
286 fmt=$1
288 shift
289 printf "*** ${fmt}\\n" "${@}"
290 printf "${fmt}" "${@}" >&5
293 _check_preface() {
294 variable=$1 topic=$2 define=$3
296 echo '**********'
297 msg "checking ${topic} ... "
298 echo "/* checked ${topic} */" >> ${h}
299 ${rm} -f ${tmp} ${tmp}.o
300 echo '*** test program is'
301 ${tee} ${tmp}.c
302 #echo '*** the preprocessor generates'
303 #${make} -f ${makefile} ${tmp}.x
304 #${cat} ${tmp}.x
305 echo '*** results are'
308 compile_check() {
309 variable=$1 topic=$2 define=$3
311 _check_preface "${variable}" "${topic}" "${define}"
313 if ${make} -f ${makefile} XINCS="${INCS}" ./${tmp}.o &&
314 [ -f ./${tmp}.o ]; then
315 msg "yes\\n"
316 echo "${define}" >> ${h}
317 eval have_${variable}=yes
318 return 0
319 else
320 echo "/* ${define} */" >> ${h}
321 msg "no\\n"
322 eval unset have_${variable}
323 return 1
327 _link_mayrun() {
328 run=$1 variable=$2 topic=$3 define=$4 libs=$5 incs=$6
330 _check_preface "${variable}" "${topic}" "${define}"
332 if ${make} -f ${makefile} XINCS="${INCS} ${incs}" \
333 XLIBS="${LIBS} ${libs}" ./${tmp} &&
334 [ -f ./${tmp} ] &&
335 { [ ${run} -eq 0 ] || ./${tmp}; }; then
336 echo "*** adding INCS<${incs}> LIBS<${libs}>"
337 msg "yes\\n"
338 echo "${define}" >> ${h}
339 LIBS="${LIBS} ${libs}"
340 echo "${libs}" >> ${lib}
341 INCS="${INCS} ${incs}"
342 echo "${incs}" >> ${inc}
343 eval have_${variable}=yes
344 return 0
345 else
346 msg "no\\n"
347 echo "/* ${define} */" >> ${h}
348 eval unset have_${variable}
349 return 1
353 link_check() {
354 _link_mayrun 0 "${1}" "${2}" "${3}" "${4}" "${5}"
357 run_check() {
358 _link_mayrun 1 "${1}" "${2}" "${3}" "${4}" "${5}"
361 # Build a basic set of INCS and LIBS according to user environment.
362 # On pkgsrc(7) systems automatically add /usr/pkg/*
363 if [ -n "${C_INCLUDE_PATH}" ]; then
364 i=${IFS}
365 IFS=:
366 set -- ${C_INCLUDE_PATH}
367 IFS=${i}
368 # for i; do -- new in POSIX Issue 7 + TC1
369 for i
371 [ "${i}" = '/usr/pkg/include' ] && continue
372 INCS="${INCS} -I${i}"
373 done
375 [ -d /usr/pkg/include ] && INCS="${INCS} -I/usr/pkg/include"
376 echo "${INCS}" >> ${inc}
378 if [ -n "${LD_LIBRARY_PATH}" ]; then
379 i=${IFS}
380 IFS=:
381 set -- ${LD_LIBRARY_PATH}
382 IFS=${i}
383 # for i; do -- new in POSIX Issue 7 + TC1
384 for i
386 [ "${i}" = '/usr/pkg/lib' ] && continue
387 LIBS="${LIBS} -L${i}"
388 done
390 [ -d /usr/pkg/lib ] && LIBS="${LIBS} -L/usr/pkg/lib"
391 echo "${LIBS}" >> ${lib}
395 # Better set _GNU_SOURCE (if we are on Linux only?); 'surprised it did without
396 echo '#define _GNU_SOURCE' >> ${h}
398 link_check hello 'if a hello world program can be built' << \! || {\
399 echo >&5 'This oooops is most certainly not related to me.';\
400 echo >&5 "Read the file ${log} and check your compiler environment.";\
401 ${rm} -f ${lst} ${h} ${mk};\
402 exit 1;\
404 #include <stdio.h>
406 int main(int argc, char *argv[])
408 (void)argc;
409 (void)argv;
410 puts("hello world");
411 return 0;
415 link_check termios 'for termios.h and tc*() family' << \! || {\
416 echo >&5 'We require termios.h and the tc*() family of functions.';\
417 echo >&5 "That much Unix we indulge ourselfs.";\
418 ${rm} -f ${lst} ${h} ${mk};\
419 exit 1;\
421 #include <termios.h>
422 int main(void)
424 struct termios tios;
425 tcgetattr(0, &tios);
426 tcsetattr(0, TCSADRAIN | TCSAFLUSH, &tios);
427 return 0;
431 link_check snprintf 'for snprintf()' '#define HAVE_SNPRINTF' << \!
432 #include <stdio.h>
433 int main(void)
435 char b[20];
436 snprintf(b, sizeof b, "%s", "string");
437 return 0;
441 link_check putc_unlocked 'for putc_unlocked()' '#define HAVE_PUTC_UNLOCKED' <<\!
442 #include <stdio.h>
443 int main(void)
445 putc_unlocked('@', stdout);
446 return 0;
450 link_check fchdir 'for fchdir()' '#define HAVE_FCHDIR' << \!
451 #include <unistd.h>
452 int main(void)
454 fchdir(0);
455 return 0;
459 link_check mmap 'for mmap()' '#define HAVE_MMAP' << \!
460 #include <sys/types.h>
461 #include <sys/mman.h>
462 int main(void)
464 mmap(0, 0, 0, 0, 0, 0);
465 return 0;
469 link_check mremap 'for mremap()' '#define HAVE_MREMAP' << \!
470 #include <sys/types.h>
471 #include <sys/mman.h>
472 int main(void)
474 mremap(0, 0, 0, MREMAP_MAYMOVE);
475 return 0;
479 link_check setlocale 'for setlocale()' '#define HAVE_SETLOCALE' << \!
480 #include <locale.h>
481 int main(void)
483 setlocale(LC_ALL, "");
484 return 0;
488 if [ "${have_setlocale}" = yes ]; then
489 link_check c90amend1 'for ISO/IEC 9899:1990/Amendment 1:1995' \
490 '#define HAVE_C90AMEND1' << \!
491 #include <limits.h>
492 #include <stdlib.h>
493 #include <wchar.h>
494 #include <wctype.h>
495 int main(void)
497 char mbb[MB_LEN_MAX + 1];
498 wchar_t wc;
499 iswprint(L'c');
500 towupper(L'c');
501 mbtowc(&wc, "x", 1);
502 mbrtowc(&wc, "x", 1, NULL);
503 (void)wctomb(mbb, wc);
504 return (mblen("\0", 1) == 0);
508 if [ "${have_c90amend1}" = yes ]; then
509 link_check wcwidth 'for wcwidth()' '#define HAVE_WCWIDTH' << \!
510 #include <wchar.h>
511 int main(void)
513 wcwidth(L'c');
514 return 0;
519 link_check nl_langinfo 'for nl_langinfo()' '#define HAVE_NL_LANGINFO' << \!
520 #include <langinfo.h>
521 #include <stdlib.h>
522 int main(void)
524 nl_langinfo(DAY_1);
525 return (nl_langinfo(CODESET) == NULL);
528 fi # have_setlocale
530 link_check mkstemp 'for mkstemp()' '#define HAVE_MKSTEMP' << \!
531 #include <stdlib.h>
532 int main(void)
534 mkstemp("x");
535 return 0;
539 # Note: run_check, thus we also get only the desired implementation...
540 run_check realpath 'for realpath()' '#define HAVE_REALPATH' << \!
541 #include <stdlib.h>
542 int main(void)
544 char *x = realpath(".", NULL), *y = realpath("/", NULL);
545 return (x != NULL && y != NULL) ? 0 : 1;
549 link_check wordexp 'for wordexp()' '#define HAVE_WORDEXP' << \!
550 #include <wordexp.h>
551 int main(void)
553 wordexp((char *)0, (wordexp_t *)0, 0);
554 return 0;
560 if wantfeat DEBUG; then
561 echo '#define HAVE_DEBUG' >> ${h}
564 if wantfeat AMALGAMATION; then
565 echo '#define HAVE_AMALGAMATION' >> ${h}
568 if nwantfeat NOALLOCA; then
569 # Due to NetBSD PR lib/47120 it seems best not to use non-cc-builtin
570 # versions of alloca(3) since modern compilers just can't be trusted
571 # not to overoptimize and silently break some code
572 link_check alloca 'for __builtin_alloca()' \
573 '#define HAVE_ALLOCA __builtin_alloca' << \!
574 int main(void)
576 void *vp = __builtin_alloca(1);
577 return (!! vp);
582 if nwantfeat NOGETOPT; then
583 link_check getopt 'for getopt()' '#define HAVE_GETOPT' << \!
584 #include <unistd.h>
585 int main(int argc, char **argv)
587 #if defined __GLIBC__ || defined __linux__
588 Argument and option reordering is not a desired feature.
589 #else
590 getopt(argc, argv, "oPt");
591 #endif
592 return (((long)optarg + optind) & 0x7F);
599 if wantfeat ICONV; then
600 ${cat} > ${tmp2}.c << \!
601 #include <iconv.h>
602 int main(void)
604 iconv_t id;
606 id = iconv_open("foo", "bar");
607 return 0;
610 < ${tmp2}.c link_check iconv 'for iconv functionality' \
611 '#define HAVE_ICONV' ||
612 < ${tmp2}.c link_check iconv \
613 'for iconv functionality in libiconv' \
614 '#define HAVE_ICONV' '-liconv'
615 else
616 echo '/* WANT_ICONV=0 */' >> ${h}
617 fi # wantfeat ICONV
619 if wantfeat SOCKETS; then
620 compile_check arpa_inet_h 'for <arpa/inet.h>' \
621 '#define HAVE_ARPA_INET_H' << \!
622 #include "config.h"
623 #include <sys/types.h>
624 #include <sys/socket.h>
625 #include <netdb.h>
626 #include <netinet/in.h>
627 #include <arpa/inet.h>
630 ${cat} > ${tmp2}.c << \!
631 #include "config.h"
632 #include <sys/types.h>
633 #include <sys/socket.h>
634 #include <netdb.h>
635 #include <netinet/in.h>
636 #ifdef HAVE_ARPA_INET_H
637 #include <arpa/inet.h>
638 #endif
640 int main(void)
642 struct sockaddr s;
643 socket(AF_INET, SOCK_STREAM, 0);
644 connect(0, &s, 0);
645 gethostbyname("foo");
646 return 0;
650 < ${tmp2}.c link_check sockets 'for sockets in libc' \
651 '#define HAVE_SOCKETS' ||
652 < ${tmp2}.c link_check sockets 'for sockets in libnsl' \
653 '#define HAVE_SOCKETS' '-lnsl' ||
654 < ${tmp2}.c link_check sockets \
655 'for sockets in libsocket and libnsl' \
656 '#define HAVE_SOCKETS' '-lsocket -lnsl' ||
657 WANT_SOCKETS=0
659 # XXX Shouldn't it be a hard error if there is no socket support, then?
660 option_update
661 else
662 echo '/* WANT_SOCKETS=0 */' >> ${h}
663 fi # wantfeat SOCKETS
665 wantfeat SOCKETS &&
666 link_check setsockopt 'for setsockopt()' '#define HAVE_SETSOCKOPT' << \!
667 #include <sys/socket.h>
668 #include <stdlib.h>
669 int main(void)
671 int sockfd = 3;
672 setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0);
673 return 0;
677 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
678 link_check so_sndtimeo 'for SO_SNDTIMEO' '#define HAVE_SO_SNDTIMEO' << \!
679 #include <sys/socket.h>
680 #include <stdlib.h>
681 int main(void)
683 struct timeval tv;
684 int sockfd = 3;
685 tv.tv_sec = 42;
686 tv.tv_usec = 21;
687 setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
688 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
689 return 0;
693 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
694 link_check so_linger 'for SO_LINGER' '#define HAVE_SO_LINGER' << \!
695 #include <sys/socket.h>
696 #include <stdlib.h>
697 int main(void)
699 struct linger li;
700 int sockfd = 3;
701 li.l_onoff = 1;
702 li.l_linger = 42;
703 setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &li, sizeof li);
704 return 0;
708 if wantfeat IPV6; then
709 link_check ipv6 'for IPv6 functionality' '#define HAVE_IPV6' << \!
710 #include "config.h"
711 #include <sys/types.h>
712 #include <sys/socket.h>
713 #include <netdb.h>
714 #include <netinet/in.h>
715 #ifdef HAVE_ARPA_INET_H
716 #include <arpa/inet.h>
717 #endif
719 int main(void)
721 struct addrinfo a, *ap;
722 getaddrinfo("foo", "0", &a, &ap);
723 return 0;
726 else
727 echo '/* WANT_IPV6=0 */' >> ${h}
728 fi # wantfeat IPV6
730 if wantfeat IMAP; then
731 echo '#define HAVE_IMAP' >> ${h}
732 else
733 echo '/* WANT_IMAP=0 */' >> ${h}
736 if wantfeat POP3; then
737 echo '#define HAVE_POP3' >> ${h}
738 else
739 echo '/* WANT_POP3=0 */' >> ${h}
742 if wantfeat SMTP; then
743 echo '#define HAVE_SMTP' >> ${h}
744 else
745 echo '/* WANT_SMTP=0 */' >> ${h}
748 if wantfeat SSL; then
749 link_check openssl 'for sufficiently recent OpenSSL' \
750 '#define HAVE_SSL
751 #define HAVE_OPENSSL' '-lssl -lcrypto' << \!
752 #include <openssl/ssl.h>
753 #include <openssl/err.h>
754 #include <openssl/x509v3.h>
755 #include <openssl/x509.h>
756 #include <openssl/rand.h>
758 #if defined OPENSSL_NO_SSL2 && defined OPENSSL_NO_SSL3 &&\
759 defined OPENSSL_NO_TLS1
760 # error We need one of (SSLv2 and) SSLv3 and TLS1.
761 #endif
763 int main(void)
765 SSLv23_client_method();
766 #ifndef OPENSSL_NO_SSL3
767 SSLv3_client_method();
768 #endif
769 #ifndef OPENSSL_NO_TLS1
770 TLSv1_client_method();
771 # ifdef TLS1_1_VERSION
772 TLSv1_1_client_method();
773 # endif
774 # ifdef TLS1_2_VERSION
775 TLSv1_2_client_method();
776 # endif
777 #endif
778 PEM_read_PrivateKey(0, 0, 0, 0);
779 return 0;
783 if [ "${have_openssl}" = 'yes' ]; then
784 compile_check stack_of 'for OpenSSL STACK_OF()' \
785 '#define HAVE_STACK_OF' << \!
786 #include <openssl/ssl.h>
787 #include <openssl/err.h>
788 #include <openssl/x509v3.h>
789 #include <openssl/x509.h>
790 #include <openssl/rand.h>
792 int main(void)
794 STACK_OF(GENERAL_NAME) *gens = NULL;
795 printf("%p", gens); /* to make it used */
796 return 0;
800 run_check openssl_md5 'for MD5 digest in OpenSSL' \
801 '#define HAVE_OPENSSL_MD5' << \!
802 #include <string.h>
803 #include <openssl/md5.h>
805 int main(void)
807 char const dat[] = "abrakadabrafidibus";
808 char dig[16], hex[16 * 2];
809 MD5_CTX ctx;
810 size_t i, j;
812 memset(dig, 0, sizeof(dig));
813 memset(hex, 0, sizeof(hex));
814 MD5_Init(&ctx);
815 MD5_Update(&ctx, dat, sizeof(dat) - 1);
816 MD5_Final(dig, &ctx);
818 #define hexchar(n) ((n)>9 ? (n)-10+'a' : (n)+'0')
819 for (i = 0; i < sizeof(hex) / 2; i++) {
820 j = i << 1;
821 hex[j] = hexchar((dig[i] & 0xf0) >> 4);
822 hex[++j] = hexchar(dig[i] & 0x0f);
824 return !!memcmp("6d7d0a3d949da2e96f2aa010f65d8326", hex, sizeof(hex));
829 else
830 echo '/* WANT_SSL=0 */' >> ${h}
831 fi # wantfeat SSL
833 if wantfeat GSSAPI; then
834 ${cat} > ${tmp2}.c << \!
835 #include <gssapi/gssapi.h>
837 int main(void)
839 gss_import_name(0, 0, GSS_C_NT_HOSTBASED_SERVICE, 0);
840 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
841 return 0;
844 ${sed} -e '1s/gssapi\///' < ${tmp2}.c > ${tmp3}.c
846 if command -v krb5-config >/dev/null 2>&1; then
847 i=`command -v krb5-config`
848 GSSAPI_LIBS="`CFLAGS= ${i} --libs gssapi`"
849 GSSAPI_INCS="`CFLAGS= ${i} --cflags`"
850 i='for GSSAPI via krb5-config(1)'
851 else
852 GSSAPI_LIBS='-lgssapi'
853 GSSAPI_INCS=
854 i='for GSSAPI in gssapi/gssapi.h, libgssapi'
856 < ${tmp2}.c link_check gssapi \
857 "${i}" '#define HAVE_GSSAPI' \
858 "${GSSAPI_LIBS}" "${GSSAPI_INCS}" ||\
859 < ${tmp3}.c link_check gssapi \
860 'for GSSAPI in gssapi.h, libgssapi' \
861 '#define HAVE_GSSAPI
862 #define GSSAPI_REG_INCLUDE' \
863 '-lgssapi' ||\
864 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgssapi_krb5' \
865 '#define HAVE_GSSAPI' \
866 '-lgssapi_krb5' ||\
867 < ${tmp3}.c link_check gssapi \
868 'for GSSAPI in libgssapi, OpenBSD-style (pre 5.3)' \
869 '#define HAVE_GSSAPI
870 #define GSSAPI_REG_INCLUDE' \
871 '-lgssapi -lkrb5 -lcrypto' \
872 '-I/usr/include/kerberosV' ||\
873 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgss' \
874 '#define HAVE_GSSAPI' \
875 '-lgss' ||\
876 link_check gssapi 'for GSSAPI in libgssapi_krb5, old-style' \
877 '#define HAVE_GSSAPI
878 #define GSSAPI_OLD_STYLE' \
879 '-lgssapi_krb5' << \!
880 #include <gssapi/gssapi.h>
881 #include <gssapi/gssapi_generic.h>
883 int main(void)
885 gss_import_name(0, 0, gss_nt_service_name, 0);
886 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
887 return 0;
890 else
891 echo '/* WANT_GSSAPI=0 */' >> ${h}
892 fi # wantfeat GSSAPI
894 if wantfeat IDNA; then
895 link_check idna 'for GNU Libidn' '#define HAVE_IDNA' '-lidn' << \!
896 #include <idna.h>
897 #include <stringprep.h>
898 int main(void)
900 char *utf8, *idna_ascii, *idna_utf8;
901 utf8 = stringprep_locale_to_utf8("does.this.work");
902 if (idna_to_ascii_8z(utf8, &idna_ascii, IDNA_USE_STD3_ASCII_RULES)
903 != IDNA_SUCCESS)
904 return 1;
905 /* (Rather link check only here) */
906 idna_utf8 = stringprep_convert(idna_ascii, "UTF-8", "de_DE");
907 return 0;
910 else
911 echo '/* WANT_IDNA=0 */' >> ${h}
914 if wantfeat REGEX; then
915 link_check regex 'for regular expressions' '#define HAVE_REGEX' << \!
916 #include <regex.h>
917 #include <stdlib.h>
918 int main(void)
920 int status;
921 regex_t re;
922 if (regcomp(&re, ".*bsd", REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
923 return 1;
924 status = regexec(&re, "plan9", 0,NULL, 0);
925 regfree(&re);
926 return !(status == REG_NOMATCH);
929 else
930 echo '/* WANT_REGEX=0 */' >> ${h}
933 if wantfeat READLINE; then
934 __edrdlib() {
935 link_check readline "for readline(3) (${1})" \
936 '#define HAVE_READLINE' "${1}" << \!
937 #include <stdio.h>
938 #include <readline/history.h>
939 #include <readline/readline.h>
940 int main(void)
942 char *rl;
943 using_history();
944 read_history("");
945 stifle_history(242);
946 rl = readline("Enter a line:");
947 if (rl && *rl)
948 add_history(rl);
949 write_history("");
950 rl_extend_line_buffer(10);
951 rl_point = rl_end = 10;
952 rl_pre_input_hook = (rl_hook_func_t*)NULL;
953 rl_forced_update_display();
955 rl_free_line_state();
956 rl_cleanup_after_signal();
957 rl_reset_after_signal();
958 return 0;
963 __edrdlib -lreadline ||
964 __edrdlib '-lreadline -ltermcap'
965 [ -n "${have_readline}" ] && WANT_TABEXPAND=1
968 if wantfeat EDITLINE && [ -z "${have_readline}" ]; then
969 __edlib() {
970 link_check editline "for editline(3) (${1})" \
971 '#define HAVE_EDITLINE' "${1}" << \!
972 #include <histedit.h>
973 static char * getprompt(void) { return (char*)"ok"; }
974 int main(void)
976 HistEvent he;
977 EditLine *el_el = el_init("TEST", stdin, stdout, stderr);
978 History *el_hcom = history_init();
979 history(el_hcom, &he, H_SETSIZE, 242);
980 el_set(el_el, EL_SIGNAL, 0);
981 el_set(el_el, EL_TERMINAL, NULL);
982 el_set(el_el, EL_HIST, &history, el_hcom);
983 el_set(el_el, EL_EDITOR, "emacs");
984 el_set(el_el, EL_PROMPT, &getprompt);
985 el_source(el_el, NULL);
986 el_end(el_el);
987 /* TODO add loader and addfn checks */
988 history_end(el_hcom);
989 return 0;
994 __edlib -ledit ||
995 __edlib '-ledit -ltermcap'
996 [ -n "${have_editline}" ] && WANT_TABEXPAND=0
999 if wantfeat NCL && [ -z "${have_editline}" ] && [ -z "${have_readline}" ] &&\
1000 [ -n "${have_c90amend1}" ]; then
1001 have_ncl=1
1002 echo '#define HAVE_NCL' >> ${h}
1003 else
1004 echo '/* WANT_{READLINE,EDITLINE,NCL}=0 */' >> ${h}
1007 if [ -n "${have_ncl}" ] || [ -n "${have_editline}" ] ||\
1008 [ -n "${have_readline}" ]; then
1009 have_cle=1
1012 if [ -n "${have_cle}" ] && wantfeat TABEXPAND; then
1013 echo '#define HAVE_TABEXPAND' >> ${h}
1014 else
1015 echo '/* WANT_TABEXPAND=0 */' >> ${h}
1018 if [ -n "${have_cle}" ] && wantfeat HISTORY; then
1019 echo '#define HAVE_HISTORY' >> ${h}
1020 else
1021 echo '/* WANT_HISTORY=0 */' >> ${h}
1024 if wantfeat QUOTE_FOLD &&\
1025 [ -n "${have_c90amend1}" ] && [ -n "${have_wcwidth}" ]; then
1026 echo '#define HAVE_QUOTE_FOLD' >> ${h}
1027 else
1028 echo '/* WANT_QUOTE_FOLD=0 */' >> ${h}
1031 if wantfeat DOCSTRINGS; then
1032 echo '#define HAVE_DOCSTRINGS' >> ${h}
1033 else
1034 echo '/* WANT_DOCSTRINGS=0 */' >> ${h}
1037 if wantfeat SPAM; then
1038 echo '#define HAVE_SPAM' >> ${h}
1039 if command -v spamc >/dev/null 2>&1; then
1040 echo "#define SPAMC_PATH \"`command -v spamc`\"" >> ${h}
1042 else
1043 echo '/* WANT_SPAM=0 */' >> ${h}
1046 if wantfeat MD5; then
1047 echo '#define HAVE_MD5' >> ${h}
1048 else
1049 echo '/* WANT_MD5=0 */' >> ${h}
1052 ## Summarizing ##
1054 # Since we cat(1) the content of those to cc/"ld", convert them to single line
1055 squeeze_em() {
1056 < "${1}" > "${2}" ${awk} \
1057 'BEGIN {ORS = " "} /^[^#]/ {print} {next} END {ORS = ""; print "\n"}'
1059 ${rm} -f ${tmp}
1060 squeeze_em ${inc} ${tmp}
1061 ${mv} ${tmp} ${inc}
1062 squeeze_em ${lib} ${tmp}
1063 ${mv} ${tmp} ${lib}
1065 # config.h
1066 ${mv} ${h} ${tmp}
1067 printf '#ifndef _CONFIG_H\n# define _CONFIG_H\n' > ${h}
1068 ${cat} ${tmp} >> ${h}
1070 printf '\n/* The "feature string", for "simplicity" and lex.c */\n' >> ${h}
1071 printf '#ifdef _MAIN_SOURCE\n' >> ${h}
1072 printf '# ifdef HAVE_AMALGAMATION\nstatic\n# endif\n' >> ${h}
1073 printf 'char const features[] = "MIME"\n' >> ${h}
1074 printf '# ifdef HAVE_DOCSTRINGS\n ",DOCSTRINGS"\n# endif\n' >> ${h}
1075 printf '# ifdef HAVE_ICONV\n ",ICONV"\n# endif\n' >> ${h}
1076 printf '# ifdef HAVE_SETLOCALE\n ",LOCALES"\n# endif\n' >> ${h}
1077 printf '# ifdef HAVE_C90AMEND1\n ",MULTIBYTE CHARSETS"\n# endif\n' >> ${h}
1078 printf '# ifdef HAVE_NL_LANGINFO\n ",TERMINAL CHARSET"\n# endif\n' >> ${h}
1079 printf '# ifdef HAVE_SOCKETS\n ",NETWORK"\n# endif\n' >> ${h}
1080 printf '# ifdef HAVE_IPV6\n ",IPv6"\n# endif\n' >> ${h}
1081 printf '# ifdef HAVE_SSL\n ",S/MIME,SSL/TSL"\n# endif\n' >> ${h}
1082 printf '# ifdef HAVE_IMAP\n ",IMAP"\n# endif\n' >> ${h}
1083 printf '# ifdef HAVE_GSSAPI\n ",GSSAPI"\n# endif\n' >> ${h}
1084 printf '# ifdef HAVE_POP3\n ",POP3"\n# endif\n' >> ${h}
1085 printf '# ifdef HAVE_SMTP\n ",SMTP"\n# endif\n' >> ${h}
1086 printf '# ifdef HAVE_SPAM\n ",SPAM"\n# endif\n' >> ${h}
1087 printf '# ifdef HAVE_IDNA\n ",IDNA"\n# endif\n' >> ${h}
1088 printf '# ifdef HAVE_REGEX\n ",REGEX"\n# endif\n' >> ${h}
1089 printf '# ifdef HAVE_READLINE\n ",READLINE"\n# endif\n' >> ${h}
1090 printf '# ifdef HAVE_EDITLINE\n ",EDITLINE"\n# endif\n' >> ${h}
1091 printf '# ifdef HAVE_NCL\n ",NCL"\n# endif\n' >> ${h}
1092 printf '# ifdef HAVE_TABEXPAND\n ",TABEXPAND"\n# endif\n' >> ${h}
1093 printf '# ifdef HAVE_HISTORY\n ",HISTORY MANAGEMENT"\n# endif\n' >> ${h}
1094 printf '# ifdef HAVE_QUOTE_FOLD\n ",QUOTE-FOLD"\n# endif\n' >> ${h}
1095 printf '# ifdef HAVE_DEBUG\n ",DEBUG"\n# endif\n' >> ${h}
1096 printf ';\n#endif /* _MAIN_SOURCE */\n' >> ${h}
1098 printf '#endif /* _CONFIG_H */\n' >> ${h}
1099 ${rm} -f ${tmp}
1101 # Create the real mk.mk
1102 ${rm} -rf ${tmp0}.* ${tmp0}*
1103 printf 'OBJ_SRC = ' >> ${mk}
1104 if nwantfeat AMALGAMATION; then
1105 echo *.c >> ${mk}
1106 echo 'OBJ_DEP =' >> ${mk}
1107 else
1108 j=`echo "${src}" | sed 's/^.\///'`
1109 echo "${j}" >> ${mk}
1110 printf 'OBJ_DEP = main.c ' >> ${mk}
1111 printf '#define _MAIN_SOURCE\n' >> ${src}
1112 printf '#include "nail.h"\n#include "main.c"\n' >> ${src}
1113 for i in *.c; do
1114 if [ "${i}" = "${j}" ] || [ "${i}" = main.c ]; then
1115 continue
1117 printf "${i} " >> ${mk}
1118 printf "#include \"${i}\"\n" >> ${src}
1119 done
1120 echo >> ${mk}
1123 echo "LIBS = `${cat} ${lib}`" >> ${mk}
1124 echo "INCLUDES = `${cat} ${inc}`" >> ${mk}
1125 echo >> ${mk}
1126 ${cat} ./mk-mk.in >> ${mk}
1128 ## Finished! ##
1130 ${cat} > ${tmp2}.c << \!
1131 #include "config.h"
1132 #ifdef HAVE_NL_LANGINFO
1133 # include <langinfo.h>
1134 #endif
1136 :The following optional features are enabled:
1137 #ifdef HAVE_ICONV
1138 : + Character set conversion using iconv()
1139 #endif
1140 #ifdef HAVE_SETLOCALE
1141 : + Locale support: Printable characters depend on the environment
1142 # ifdef HAVE_C90AMEND1
1143 : + Multibyte character support
1144 # endif
1145 # ifdef HAVE_NL_LANGINFO
1146 : + Automatic detection of terminal character set
1147 # endif
1148 #endif
1149 #ifdef HAVE_SOCKETS
1150 : + Network support
1151 #endif
1152 #ifdef HAVE_IPV6
1153 : + Support for Internet Protocol v6 (IPv6)
1154 #endif
1155 #ifdef HAVE_SSL
1156 # ifdef HAVE_OPENSSL
1157 : + S/MIME and SSL/TLS using OpenSSL
1158 # endif
1159 #endif
1160 #ifdef HAVE_IMAP
1161 : + IMAP protocol
1162 #endif
1163 #ifdef HAVE_GSSAPI
1164 : + IMAP GSSAPI authentication
1165 #endif
1166 #ifdef HAVE_POP3
1167 : + POP3 protocol
1168 #endif
1169 #ifdef HAVE_SMTP
1170 : + SMTP protocol
1171 #endif
1172 #ifdef HAVE_SPAM
1173 : + Interaction with spam filters
1174 #endif
1175 #ifdef HAVE_IDNA
1176 : + IDNA (internationalized domain names for applications) support
1177 #endif
1178 #ifdef HAVE_REGEX
1179 : + Regular expression searches
1180 #endif
1181 #if defined HAVE_READLINE || defined HAVE_EDITLINE || defined HAVE_NCL
1182 : + Command line editing
1183 # ifdef HAVE_TABEXPAND
1184 : + + Tabulator expansion
1185 # endif
1186 # ifdef HAVE_HISTORY
1187 : + + History management
1188 # endif
1189 #endif
1190 #ifdef HAVE_QUOTE_FOLD
1191 : + Extended *quote-fold*ing
1192 #endif
1194 :The following optional features are disabled:
1195 #ifndef HAVE_ICONV
1196 : - Character set conversion using iconv()
1197 #endif
1198 #ifndef HAVE_SETLOCALE
1199 : - Locale support: Only ASCII characters are recognized
1200 #endif
1201 # ifndef HAVE_C90AMEND1
1202 : - Multibyte character support
1203 # endif
1204 # ifndef HAVE_NL_LANGINFO
1205 : - Automatic detection of terminal character set
1206 # endif
1207 #ifndef HAVE_SOCKETS
1208 : - Network support
1209 #endif
1210 #ifndef HAVE_IPV6
1211 : - Support for Internet Protocol v6 (IPv6)
1212 #endif
1213 #if !defined HAVE_SSL
1214 : - SSL/TLS (network transport authentication and encryption)
1215 #endif
1216 #ifndef HAVE_IMAP
1217 : - IMAP protocol
1218 #endif
1219 #ifndef HAVE_GSSAPI
1220 : - IMAP GSSAPI authentication
1221 #endif
1222 #ifndef HAVE_POP3
1223 : - POP3 protocol
1224 #endif
1225 #ifndef HAVE_SMTP
1226 : - SMTP protocol
1227 #endif
1228 #ifndef HAVE_SPAM
1229 : - Interaction with spam filters
1230 #endif
1231 #ifndef HAVE_IDNA
1232 : - IDNA (internationalized domain names for applications) support
1233 #endif
1234 #ifndef HAVE_REGEX
1235 : - Regular expression searches
1236 #endif
1237 #if !defined HAVE_READLINE && !defined HAVE_EDITLINE && !defined HAVE_NCL
1238 : - Command line editing and history
1239 #endif
1240 #ifndef HAVE_QUOTE_FOLD
1241 : - Extended *quote-fold*ing
1242 #endif
1244 :Remarks:
1245 #ifndef HAVE_SNPRINTF
1246 : . The function snprintf() could not be found. mailx will be compiled to use
1247 : sprintf() instead. This might overflow buffers if input values are larger
1248 : than expected. Use the resulting binary with care or update your system
1249 : environment and start the configuration process again.
1250 #endif
1251 #ifndef HAVE_FCHDIR
1252 : . The function fchdir() could not be found. mailx will be compiled to use
1253 : chdir() instead. This is not a problem unless the current working
1254 : directory of mailx is moved while the IMAP cache is used.
1255 #endif
1256 #ifndef HAVE_GETOPT
1257 : . Using a minimal builtin POSIX-like getopt()
1258 #endif
1259 #ifdef HAVE_DEBUG
1260 : . Debug enabled binary: not meant to be used by end-users: THANKS!
1261 #endif
1265 ${make} -f ${makefile} ${tmp2}.x
1266 < ${tmp2}.x >&5 ${sed} -e '/^[^:]/d; /^$/d; s/^://'
1268 # vim:set fenc=utf-8:s-it-mode