INSTALL: more on v14.5
[s-mailx.git] / mk-conf.sh
blob7a4409964edb8a15dc4df32e9a60570508e6620e
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 i=`${CC} --version 2>/dev/null`
102 stackprot=no
103 if 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 echo "${i}" | ${grep} -q gcc; then
113 _CFLAGS="${_CFLAGS} -fstrict-overflow -Wstrict-overflow=5"
114 else
115 _CFLAGS="${_CFLAGS} -Wno-long-long"
116 if echo "${i}" | ${grep} -q -e 'version 1'; then
118 else
119 _CFLAGS="${_CFLAGS} -fstrict-overflow -Wstrict-overflow=5"
122 # elif echo "${i}" | ${grep} -q -i clang; then
123 # stackprot=yes
124 # _CFLAGS='-std=c89 -O3 -g -Weverything -Wno-long-long'
125 elif [ -z "${_CFLAGS}" ]; then
126 _CFLAGS=-O1
129 if nwantfeat DEBUG; then
130 _CFLAGS="${_CFLAGS} -DNDEBUG"
131 else
132 _CFLAGS="${_CFLAGS} -g";
133 if [ "${stackprot}" = yes ]; then
134 _CFLAGS="${_CFLAGS} -fstack-protector-all "
135 _CFLAGS="${_CFLAGS} -Wstack-protector -D_FORTIFY_SOURCE=2"
138 _CFLAGS="${_CFLAGS} ${ADDCFLAGS}"
139 _LDFLAGS="${_LDFLAGS} ${ADDLDFLAGS}" # XXX -Wl,--sort-common,[-O1]
140 export _CFLAGS _LDFLAGS
142 if wantfeat AUTOCC || [ -z "${CFLAGS}" ]; then
143 CFLAGS=$_CFLAGS
144 export CFLAGS
146 if wantfeat AUTOCC || [ -z "${LDFLAGS}" ]; then
147 LDFLAGS=$_LDFLAGS
148 export LDFLAGS
152 ## -- >8 -- 8< -- ##
154 ## Notes:
155 ## - Heirloom sh(1) (and same origin) have problems with ': >' redirection,
156 ## so use "printf '' >" instead
157 ## - Heirloom sh(1) and maybe more execute loops with redirection in a subshell
158 ## (but don't export eval's from within), therefore we need to (re)include
159 ## variable assignments at toplevel instead (via reading temporary files)
161 ## First of all, create new configuration and check wether it changed ##
163 conf=./conf.rc
164 lst=./config.lst
165 h=./config.h
166 mk=./mk.mk
168 newlst=./config.lst-new
169 newmk=./config.mk-new
170 newh=./config.h-new
171 tmp0=___tmp
172 tmp=./${tmp0}1$$
174 # Only incorporate what wasn't overwritten from command line / CONFIG
175 trap "${rm} -f ${tmp}; exit" 1 2 15
176 trap "${rm} -f ${tmp}" 0
177 ${rm} -f ${tmp}
179 < ${conf} ${sed} -e '/^[ \t]*#/d' -e '/^$/d' -e 's/[ \t]*$//' |
180 while read line; do
181 i=`echo ${line} | ${sed} -e 's/=.*$//'`
182 eval j=\$${i} jx=\${${i}+x}
183 if [ -n "${j}" ] || [ "${jx}" = x ]; then
184 line="${i}=\"${j}\""
186 echo ${line}
187 done > ${tmp}
188 . ./${tmp}
190 wantfeat() {
191 eval i=\$WANT_${1}
192 [ "${i}" = "1" ]
194 nwantfeat() {
195 eval i=\$WANT_${1}
196 [ "${i}" != "1" ]
199 option_update
201 # (No function since some shells loose non-exported variables in traps)
202 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}; exit" 1 2 15
203 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}" 0
204 ${rm} -f ${newlst} ${newmk} ${newh}
206 while read line; do
207 i=`echo ${line} | ${sed} -e 's/=.*$//'`
208 eval j=\$${i}
209 if [ -z "${j}" ] || [ "${j}" = 0 ]; then
210 printf "/*#define ${i}*/\n" >> ${newh}
211 elif [ "${j}" = 1 ]; then
212 printf "#define ${i}\n" >> ${newh}
213 else
214 printf "#define ${i} \"${j}\"\n" >> ${newh}
216 printf "${i} = ${j}\n" >> ${newmk}
217 printf "${i}=\"${j}\"\n"
218 done < ${tmp} > ${newlst}
219 . ./${newlst}
221 printf "#define UAGENT \"${SID}${NAIL}\"\n" >> ${newh}
222 printf "UAGENT = ${SID}${NAIL}\n" >> ${newmk}
224 compiler_flags
226 printf "CC = ${CC}\n" >> ${newmk}
227 printf "_CFLAGS = ${_CFLAGS}\nCFLAGS = ${CFLAGS}\n" >> ${newmk}
228 printf "_LDFLAGS = ${_LDFLAGS}\nLDFLAGS = ${LDFLAGS}\n" >> ${newmk}
229 printf "CMP=${cmp}\nCHMOD=${chmod}\nCP=${cp}\nMKDIR=${mkdir}\nRM=${rm}\n"\
230 >> ${newmk}
231 printf "STRIP=${STRIP}\nHAVE_STRIP=${HAVE_STRIP}\n" >> ${newmk}
232 # (We include the cc(1)/ld(1) environment only for update detection..)
233 printf "CC=\"${CC}\"\n" >> ${newlst}
234 printf "_CFLAGS=\"${_CFLAGS}\"\nCFLAGS=\"${CFLAGS}\"\n" >> ${newlst}
235 printf "_LDFLAGS=\"${_LDFLAGS}\"\nLDFLAGS=\"${LDFLAGS}\"\n" >> ${newlst}
236 printf "CMP=${cmp}\nCHMOD=${chmod}\nCP=${cp}\nMKDIR=${mkdir}\nRM=${rm}\n"\
237 >> ${newlst}
238 printf "STRIP=${STRIP}\nHAVE_STRIP=${HAVE_STRIP}\n" >> ${newlst}
240 if [ -f ${lst} ] && ${cmp} ${newlst} ${lst} >/dev/null 2>&1; then
241 exit 0
243 [ -f ${lst} ] && echo 'configuration updated..' || echo 'shiny configuration..'
245 ${mv} -f ${newlst} ${lst}
246 ${mv} -f ${newh} ${h}
247 ${mv} -f ${newmk} ${mk}
249 ## Compile and link checking ##
251 tmp2=./${tmp0}2$$
252 tmp3=./${tmp0}3$$
253 log=./config.log
254 lib=./config.lib
255 inc=./config.inc
256 src=./config.c
257 makefile=./config.mk
259 # (No function since some shells loose non-exported variables in traps)
260 trap "${rm} -f ${lst} ${h} ${mk} ${lib} ${inc} ${src} ${makefile}; exit" 1 2 15
261 trap "${rm} -rf ${tmp0}.* ${tmp0}* ${makefile}" 0
263 exec 5>&2 > ${log} 2>&1
264 printf '' > ${lib}
265 printf '' > ${inc}
266 # ${src} is only created if WANT_AMALGAMATION
267 ${rm} -f ${src}
268 ${cat} > ${makefile} << \!
269 .SUFFIXES: .o .c .x .y
270 .c.o:
271 $(CC) $(XINCS) -c $<
272 .c.x:
273 $(CC) $(XINCS) -E $< >$@
275 $(CC) $(XINCS) -o $@ $< $(XLIBS)
276 .y: ;
279 msg() {
280 fmt=$1
282 shift
283 printf "*** ${fmt}\\n" "${@}"
284 printf "${fmt}" "${@}" >&5
287 _check_preface() {
288 variable=$1 topic=$2 define=$3
290 echo '**********'
291 msg "checking ${topic} ... "
292 echo "/* checked ${topic} */" >> ${h}
293 ${rm} -f ${tmp} ${tmp}.o
294 echo '*** test program is'
295 ${tee} ${tmp}.c
296 #echo '*** the preprocessor generates'
297 #${make} -f ${makefile} ${tmp}.x
298 #${cat} ${tmp}.x
299 echo '*** results are'
302 compile_check() {
303 variable=$1 topic=$2 define=$3
305 _check_preface "${variable}" "${topic}" "${define}"
307 if ${make} -f ${makefile} XINCS="${INCS}" ./${tmp}.o &&
308 [ -f ./${tmp}.o ]; then
309 msg "yes\\n"
310 echo "${define}" >> ${h}
311 eval have_${variable}=yes
312 return 0
313 else
314 echo "/* ${define} */" >> ${h}
315 msg "no\\n"
316 eval unset have_${variable}
317 return 1
321 _link_mayrun() {
322 run=$1 variable=$2 topic=$3 define=$4 libs=$5 incs=$6
324 _check_preface "${variable}" "${topic}" "${define}"
326 if ${make} -f ${makefile} XINCS="${INCS} ${incs}" \
327 XLIBS="${LIBS} ${libs}" ./${tmp} &&
328 [ -f ./${tmp} ] &&
329 { [ ${run} -eq 0 ] || ./${tmp}; }; then
330 echo "*** adding INCS<${incs}> LIBS<${libs}>"
331 msg "yes\\n"
332 echo "${define}" >> ${h}
333 LIBS="${LIBS} ${libs}"
334 echo "${libs}" >> ${lib}
335 INCS="${INCS} ${incs}"
336 echo "${incs}" >> ${inc}
337 eval have_${variable}=yes
338 return 0
339 else
340 msg "no\\n"
341 echo "/* ${define} */" >> ${h}
342 eval unset have_${variable}
343 return 1
347 link_check() {
348 _link_mayrun 0 "${1}" "${2}" "${3}" "${4}" "${5}"
351 run_check() {
352 _link_mayrun 1 "${1}" "${2}" "${3}" "${4}" "${5}"
355 # Build a basic set of INCS and LIBS according to user environment.
356 # On pkgsrc(7) systems automatically add /usr/pkg/*
357 if [ -n "${C_INCLUDE_PATH}" ]; then
358 i=${IFS}
359 IFS=:
360 set -- ${C_INCLUDE_PATH}
361 IFS=${i}
362 # for i; do -- new in POSIX Issue 7 + TC1
363 for i
365 [ "${i}" = '/usr/pkg/include' ] && continue
366 INCS="${INCS} -I${i}"
367 done
369 [ -d /usr/pkg/include ] && INCS="${INCS} -I/usr/pkg/include"
370 echo "${INCS}" >> ${inc}
372 if [ -n "${LD_LIBRARY_PATH}" ]; then
373 i=${IFS}
374 IFS=:
375 set -- ${LD_LIBRARY_PATH}
376 IFS=${i}
377 # for i; do -- new in POSIX Issue 7 + TC1
378 for i
380 [ "${i}" = '/usr/pkg/lib' ] && continue
381 LIBS="${LIBS} -L${i}"
382 done
384 [ -d /usr/pkg/lib ] && LIBS="${LIBS} -L/usr/pkg/lib"
385 echo "${LIBS}" >> ${lib}
389 # Better set _GNU_SOURCE (if we are on Linux only?)
390 # Fixes compilation on Slackware 14 + (with at least clang(1)).
391 # Since i've always defined this on GNU/Linux, i'm even surprised it works
392 # without!! Didn't check this yet (and TinyCore uses different environment).
393 echo '#define _GNU_SOURCE' >> ${h}
395 link_check hello 'if a hello world program can be built' << \! || {\
396 echo >&5 'This oooops is most certainly not related to me.';\
397 echo >&5 "Read the file ${log} and check your compiler environment.";\
398 ${rm} -f ${lst} ${h} ${mk};\
399 exit 1;\
401 #include <stdio.h>
403 int main(int argc, char *argv[])
405 (void)argc;
406 (void)argv;
407 puts("hello world");
408 return 0;
412 link_check termios 'for termios.h and tc*() family' << \! || {\
413 echo >&5 'We require termios.h and the tc*() family of functions.';\
414 echo >&5 "That much Unix we indulge ourselfs.";\
415 ${rm} -f ${lst} ${h} ${mk};\
416 exit 1;\
418 #include <termios.h>
419 int main(void)
421 struct termios tios;
422 tcgetattr(0, &tios);
423 tcsetattr(0, TCSADRAIN | TCSAFLUSH, &tios);
424 return 0;
428 link_check snprintf 'for snprintf()' '#define HAVE_SNPRINTF' << \!
429 #include <stdio.h>
430 int main(void)
432 char b[20];
433 snprintf(b, sizeof b, "%s", "string");
434 return 0;
438 link_check putc_unlocked 'for putc_unlocked()' '#define HAVE_PUTC_UNLOCKED' <<\!
439 #include <stdio.h>
440 int main(void)
442 putc_unlocked('@', stdout);
443 return 0;
447 link_check fchdir 'for fchdir()' '#define HAVE_FCHDIR' << \!
448 #include <unistd.h>
449 int main(void)
451 fchdir(0);
452 return 0;
456 link_check mmap 'for mmap()' '#define HAVE_MMAP' << \!
457 #include <sys/types.h>
458 #include <sys/mman.h>
459 int main(void)
461 mmap(0, 0, 0, 0, 0, 0);
462 return 0;
466 link_check mremap 'for mremap()' '#define HAVE_MREMAP' << \!
467 #include <sys/types.h>
468 #include <sys/mman.h>
469 int main(void)
471 mremap(0, 0, 0, MREMAP_MAYMOVE);
472 return 0;
476 link_check wctype 'for wctype functionality' '#define HAVE_WCTYPE_H' << \!
477 #include <wctype.h>
478 int main(void)
480 iswprint(L'c');
481 towupper(L'c');
482 return 0;
486 link_check wcwidth 'for wcwidth() ' '#define HAVE_WCWIDTH' << \!
487 #include <wchar.h>
488 int main(void)
490 wcwidth(L'c');
491 return 0;
495 link_check mbtowc 'for mbtowc()' '#define HAVE_MBTOWC' << \!
496 #include <stdlib.h>
497 int main(void)
499 wchar_t wc;
500 mbtowc(&wc, "x", 1);
501 return 0;
505 link_check mbrtowc 'for mbrtowc()' '#define HAVE_MBRTOWC' << \!
506 #include <wchar.h>
507 int main(void)
509 wchar_t wc;
510 mbrtowc(&wc, "x", 1, NULL);
511 return 0;
515 link_check mblen 'for mblen()' '#define HAVE_MBLEN' << \!
516 #include <stdlib.h>
517 int main(void)
519 return mblen("\0", 1) == 0;
523 link_check setlocale 'for setlocale()' '#define HAVE_SETLOCALE' << \!
524 #include <locale.h>
525 int main(void)
527 setlocale(LC_ALL, "");
528 return 0;
532 link_check nl_langinfo 'for nl_langinfo()' '#define HAVE_NL_LANGINFO' << \!
533 #include <langinfo.h>
534 int main(void)
536 nl_langinfo(DAY_1);
537 return 0;
541 link_check mkstemp 'for mkstemp()' '#define HAVE_MKSTEMP' << \!
542 #include <stdlib.h>
543 int main(void)
545 mkstemp("x");
546 return 0;
550 # Note: run_check, thus we also get only the desired implementation...
551 run_check realpath 'for realpath()' '#define HAVE_REALPATH' << \!
552 #include <stdlib.h>
553 int main(void)
555 char *x = realpath(".", NULL), *y = realpath("/", NULL);
556 return (x != NULL && y != NULL) ? 0 : 1;
560 link_check wordexp 'for wordexp()' '#define HAVE_WORDEXP' << \!
561 #include <wordexp.h>
562 int main(void)
564 wordexp((char *)0, (wordexp_t *)0, 0);
565 return 0;
571 if wantfeat DEBUG; then
572 echo '#define HAVE_DEBUG' >> ${h}
575 if wantfeat AMALGAMATION; then
576 echo '#define HAVE_AMALGAMATION' >> ${h}
579 if nwantfeat NOALLOCA; then
580 # Due to NetBSD PR lib/47120 it seems best not to use non-cc-builtin
581 # versions of alloca(3) since modern compilers just can't be trusted
582 # not to overoptimize and silently break some code
583 link_check alloca 'for __builtin_alloca()' \
584 '#define HAVE_ALLOCA __builtin_alloca' << \!
585 int main(void)
587 void *vp = __builtin_alloca(1);
588 return (!! vp);
593 if nwantfeat NOGETOPT; then
594 link_check getopt 'for getopt()' '#define HAVE_GETOPT' << \!
595 #include <unistd.h>
596 int main(int argc, char **argv)
598 #if defined __GLIBC__ || defined __linux__
599 Argument and option reordering is not a desired feature.
600 #else
601 getopt(argc, argv, "oPt");
602 #endif
603 return (((long)optarg + optind) & 0x7F);
610 if wantfeat ICONV; then
611 ${cat} > ${tmp2}.c << \!
612 #include <iconv.h>
613 int main(void)
615 iconv_t id;
617 id = iconv_open("foo", "bar");
618 return 0;
621 < ${tmp2}.c link_check iconv 'for iconv functionality' \
622 '#define HAVE_ICONV' ||
623 < ${tmp2}.c link_check iconv \
624 'for iconv functionality in libiconv' \
625 '#define HAVE_ICONV' '-liconv'
626 else
627 echo '/* WANT_ICONV=0 */' >> ${h}
628 fi # wantfeat ICONV
630 if wantfeat SOCKETS; then
631 compile_check arpa_inet_h 'for <arpa/inet.h>' \
632 '#define HAVE_ARPA_INET_H' << \!
633 #include "config.h"
634 #include <sys/types.h>
635 #include <sys/socket.h>
636 #include <netdb.h>
637 #include <netinet/in.h>
638 #include <arpa/inet.h>
641 ${cat} > ${tmp2}.c << \!
642 #include "config.h"
643 #include <sys/types.h>
644 #include <sys/socket.h>
645 #include <netdb.h>
646 #include <netinet/in.h>
647 #ifdef HAVE_ARPA_INET_H
648 #include <arpa/inet.h>
649 #endif
651 int main(void)
653 struct sockaddr s;
654 socket(AF_INET, SOCK_STREAM, 0);
655 connect(0, &s, 0);
656 gethostbyname("foo");
657 return 0;
661 < ${tmp2}.c link_check sockets 'for sockets in libc' \
662 '#define HAVE_SOCKETS' ||
663 < ${tmp2}.c link_check sockets 'for sockets in libnsl' \
664 '#define HAVE_SOCKETS' '-lnsl' ||
665 < ${tmp2}.c link_check sockets \
666 'for sockets in libsocket and libnsl' \
667 '#define HAVE_SOCKETS' '-lsocket -lnsl' ||
668 WANT_SOCKETS=0
670 # XXX Shouldn't it be a hard error if there is no socket support, then?
671 option_update
672 else
673 echo '/* WANT_SOCKETS=0 */' >> ${h}
674 fi # wantfeat SOCKETS
676 wantfeat SOCKETS &&
677 link_check setsockopt 'for setsockopt()' '#define HAVE_SETSOCKOPT' << \!
678 #include <sys/socket.h>
679 #include <stdlib.h>
680 int main(void)
682 int sockfd = 3;
683 setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0);
684 return 0;
688 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
689 link_check so_sndtimeo 'for SO_SNDTIMEO' '#define HAVE_SO_SNDTIMEO' << \!
690 #include <sys/socket.h>
691 #include <stdlib.h>
692 int main(void)
694 struct timeval tv;
695 int sockfd = 3;
696 tv.tv_sec = 42;
697 tv.tv_usec = 21;
698 setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
699 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
700 return 0;
704 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
705 link_check so_linger 'for SO_LINGER' '#define HAVE_SO_LINGER' << \!
706 #include <sys/socket.h>
707 #include <stdlib.h>
708 int main(void)
710 struct linger li;
711 int sockfd = 3;
712 li.l_onoff = 1;
713 li.l_linger = 42;
714 setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &li, sizeof li);
715 return 0;
719 if wantfeat IPV6; then
720 link_check ipv6 'for IPv6 functionality' '#define HAVE_IPV6' << \!
721 #include "config.h"
722 #include <sys/types.h>
723 #include <sys/socket.h>
724 #include <netdb.h>
725 #include <netinet/in.h>
726 #ifdef HAVE_ARPA_INET_H
727 #include <arpa/inet.h>
728 #endif
730 int main(void)
732 struct addrinfo a, *ap;
733 getaddrinfo("foo", "0", &a, &ap);
734 return 0;
737 else
738 echo '/* WANT_IPV6=0 */' >> ${h}
739 fi # wantfeat IPV6
741 if wantfeat IMAP; then
742 echo '#define HAVE_IMAP' >> ${h}
743 else
744 echo '/* WANT_IMAP=0 */' >> ${h}
747 if wantfeat POP3; then
748 echo '#define HAVE_POP3' >> ${h}
749 else
750 echo '/* WANT_POP3=0 */' >> ${h}
753 if wantfeat SMTP; then
754 echo '#define HAVE_SMTP' >> ${h}
755 else
756 echo '/* WANT_SMTP=0 */' >> ${h}
759 if wantfeat SSL; then
760 link_check openssl 'for sufficiently recent OpenSSL' \
761 '#define HAVE_SSL
762 #define HAVE_OPENSSL' '-lssl -lcrypto' << \!
763 #include <openssl/ssl.h>
764 #include <openssl/err.h>
765 #include <openssl/x509v3.h>
766 #include <openssl/x509.h>
767 #include <openssl/rand.h>
769 #if defined OPENSSL_NO_SSL2 && defined OPENSSL_NO_SSL3 &&\
770 defined OPENSSL_NO_TLS1
771 # error We need one of (SSLv2 and) SSLv3 and TLS1.
772 #endif
774 int main(void)
776 SSLv23_client_method();
777 #ifndef OPENSSL_NO_SSL3
778 SSLv3_client_method();
779 #endif
780 #ifndef OPENSSL_NO_TLS1
781 TLSv1_client_method();
782 # ifdef TLS1_1_VERSION
783 TLSv1_1_client_method();
784 # endif
785 # ifdef TLS1_2_VERSION
786 TLSv1_2_client_method();
787 # endif
788 #endif
789 PEM_read_PrivateKey(0, 0, 0, 0);
790 return 0;
794 if [ "${have_openssl}" = 'yes' ]; then
795 compile_check stack_of 'for OpenSSL STACK_OF()' \
796 '#define HAVE_STACK_OF' << \!
797 #include <openssl/ssl.h>
798 #include <openssl/err.h>
799 #include <openssl/x509v3.h>
800 #include <openssl/x509.h>
801 #include <openssl/rand.h>
803 int main(void)
805 STACK_OF(GENERAL_NAME) *gens = NULL;
806 printf("%p", gens); /* to make it used */
807 return 0;
811 run_check openssl_md5 'for MD5 digest in OpenSSL' \
812 '#define HAVE_OPENSSL_MD5' << \!
813 #include <string.h>
814 #include <openssl/md5.h>
816 int main(void)
818 char const dat[] = "abrakadabrafidibus";
819 char dig[16], hex[16 * 2];
820 MD5_CTX ctx;
821 size_t i, j;
823 memset(dig, 0, sizeof(dig));
824 memset(hex, 0, sizeof(hex));
825 MD5_Init(&ctx);
826 MD5_Update(&ctx, dat, sizeof(dat) - 1);
827 MD5_Final(dig, &ctx);
829 #define hexchar(n) ((n)>9 ? (n)-10+'a' : (n)+'0')
830 for (i = 0; i < sizeof(hex) / 2; i++) {
831 j = i << 1;
832 hex[j] = hexchar((dig[i] & 0xf0) >> 4);
833 hex[++j] = hexchar(dig[i] & 0x0f);
835 return !!memcmp("6d7d0a3d949da2e96f2aa010f65d8326", hex, sizeof(hex));
840 else
841 echo '/* WANT_SSL=0 */' >> ${h}
842 fi # wantfeat SSL
844 if wantfeat GSSAPI; then
845 ${cat} > ${tmp2}.c << \!
846 #include <gssapi/gssapi.h>
848 int main(void)
850 gss_import_name(0, 0, GSS_C_NT_HOSTBASED_SERVICE, 0);
851 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
852 return 0;
855 ${sed} -e '1s/gssapi\///' < ${tmp2}.c > ${tmp3}.c
857 if command -v krb5-config >/dev/null 2>&1; then
858 i=`command -v krb5-config`
859 GSSAPI_LIBS="`CFLAGS= ${i} --libs gssapi`"
860 GSSAPI_INCS="`CFLAGS= ${i} --cflags`"
861 i='for GSSAPI via krb5-config(1)'
862 else
863 GSSAPI_LIBS='-lgssapi'
864 GSSAPI_INCS=
865 i='for GSSAPI in gssapi/gssapi.h, libgssapi'
867 < ${tmp2}.c link_check gssapi \
868 "${i}" '#define HAVE_GSSAPI' \
869 "${GSSAPI_LIBS}" "${GSSAPI_INCS}" ||\
870 < ${tmp3}.c link_check gssapi \
871 'for GSSAPI in gssapi.h, libgssapi' \
872 '#define HAVE_GSSAPI
873 #define GSSAPI_REG_INCLUDE' \
874 '-lgssapi' ||\
875 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgssapi_krb5' \
876 '#define HAVE_GSSAPI' \
877 '-lgssapi_krb5' ||\
878 < ${tmp3}.c link_check gssapi \
879 'for GSSAPI in libgssapi, OpenBSD-style (pre 5.3)' \
880 '#define HAVE_GSSAPI
881 #define GSSAPI_REG_INCLUDE' \
882 '-lgssapi -lkrb5 -lcrypto' \
883 '-I/usr/include/kerberosV' ||\
884 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgss' \
885 '#define HAVE_GSSAPI' \
886 '-lgss' ||\
887 link_check gssapi 'for GSSAPI in libgssapi_krb5, old-style' \
888 '#define HAVE_GSSAPI
889 #define GSSAPI_OLD_STYLE' \
890 '-lgssapi_krb5' << \!
891 #include <gssapi/gssapi.h>
892 #include <gssapi/gssapi_generic.h>
894 int main(void)
896 gss_import_name(0, 0, gss_nt_service_name, 0);
897 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
898 return 0;
901 else
902 echo '/* WANT_GSSAPI=0 */' >> ${h}
903 fi # wantfeat GSSAPI
905 if wantfeat IDNA; then
906 link_check idna 'for GNU Libidn' '#define HAVE_IDNA' '-lidn' << \!
907 #include <idna.h>
908 #include <stringprep.h>
909 int main(void)
911 char *utf8, *idna_ascii, *idna_utf8;
912 utf8 = stringprep_locale_to_utf8("does.this.work");
913 if (idna_to_ascii_8z(utf8, &idna_ascii, IDNA_USE_STD3_ASCII_RULES)
914 != IDNA_SUCCESS)
915 return 1;
916 /* (Rather link check only here) */
917 idna_utf8 = stringprep_convert(idna_ascii, "UTF-8", "de_DE");
918 return 0;
921 else
922 echo '/* WANT_IDNA=0 */' >> ${h}
923 fi # wantfeat IDNA
925 if wantfeat READLINE; then
926 __edrdlib() {
927 link_check readline "for readline(3) (${1})" \
928 '#define HAVE_READLINE' "${1}" << \!
929 #include <stdio.h>
930 #include <readline/history.h>
931 #include <readline/readline.h>
932 int main(void)
934 char *rl;
935 using_history();
936 read_history("");
937 stifle_history(242);
938 rl = readline("Enter a line:");
939 if (rl && *rl)
940 add_history(rl);
941 write_history("");
942 rl_extend_line_buffer(10);
943 rl_point = rl_end = 10;
944 rl_pre_input_hook = (rl_hook_func_t*)NULL;
945 rl_forced_update_display();
947 rl_free_line_state();
948 rl_cleanup_after_signal();
949 rl_reset_after_signal();
950 return 0;
955 __edrdlib -lreadline ||
956 __edrdlib '-lreadline -ltermcap'
957 [ -n "${have_readline}" ] && WANT_TABEXPAND=1
960 if wantfeat EDITLINE && [ -z "${have_readline}" ]; then
961 __edlib() {
962 link_check editline "for editline(3) (${1})" \
963 '#define HAVE_EDITLINE' "${1}" << \!
964 #include <histedit.h>
965 static char * getprompt(void) { return (char*)"ok"; }
966 int main(void)
968 HistEvent he;
969 EditLine *el_el = el_init("TEST", stdin, stdout, stderr);
970 History *el_hcom = history_init();
971 history(el_hcom, &he, H_SETSIZE, 242);
972 el_set(el_el, EL_SIGNAL, 0);
973 el_set(el_el, EL_TERMINAL, NULL);
974 el_set(el_el, EL_HIST, &history, el_hcom);
975 el_set(el_el, EL_EDITOR, "emacs");
976 el_set(el_el, EL_PROMPT, &getprompt);
977 el_source(el_el, NULL);
978 el_end(el_el);
979 /* TODO add loader and addfn checks */
980 history_end(el_hcom);
981 return 0;
986 __edlib -ledit ||
987 __edlib '-ledit -ltermcap'
988 [ -n "${have_editline}" ] && WANT_TABEXPAND=0
991 if wantfeat NCL && [ -z "${have_editline}" ] && [ -z "${have_readline}" ] &&\
992 [ -n "${have_mbrtowc}" ] && [ -n "${have_wctype}" ]; then
993 have_ncl=1
994 echo '#define HAVE_NCL' >> ${h}
995 else
996 echo '/* WANT_{READLINE,EDITLINE,NCL}=0 */' >> ${h}
999 if [ -n "${have_ncl}" ] || [ -n "${have_editline}" ] ||\
1000 [ -n "${have_readline}" ]; then
1001 have_cle=1
1004 if [ -n "${have_cle}" ] && wantfeat TABEXPAND; then
1005 echo '#define HAVE_TABEXPAND' >> ${h}
1006 else
1007 echo '/* WANT_TABEXPAND=0 */' >> ${h}
1010 if [ -n "${have_cle}" ] && wantfeat HISTORY; then
1011 echo '#define HAVE_HISTORY' >> ${h}
1012 else
1013 echo '/* WANT_HISTORY=0 */' >> ${h}
1016 if wantfeat QUOTE_FOLD &&\
1017 [ -n "${have_mbrtowc}" ] && [ -n "${have_wcwidth}" ]; then
1018 echo '#define HAVE_QUOTE_FOLD' >> ${h}
1019 else
1020 echo '/* WANT_QUOTE_FOLD=0 */' >> ${h}
1023 if wantfeat DOCSTRINGS; then
1024 echo '#define HAVE_DOCSTRINGS' >> ${h}
1025 else
1026 echo '/* WANT_DOCSTRINGS=0 */' >> ${h}
1029 if wantfeat SPAM; then
1030 echo '#define HAVE_SPAM' >> ${h}
1031 if command -v spamc >/dev/null 2>&1; then
1032 echo "#define SPAMC_PATH \"`command -v spamc`\"" >> ${h}
1034 else
1035 echo '/* WANT_SPAM=0 */' >> ${h}
1038 if wantfeat MD5; then
1039 echo '#define HAVE_MD5' >> ${h}
1040 else
1041 echo '/* WANT_MD5=0 */' >> ${h}
1044 ## Summarizing ##
1046 # Since we cat(1) the content of those to cc/"ld", convert them to single line
1047 squeeze_em() {
1048 < "${1}" > "${2}" ${awk} \
1049 'BEGIN {ORS = " "} /^[^#]/ {print} {next} END {ORS = ""; print "\n"}'
1051 ${rm} -f ${tmp}
1052 squeeze_em ${inc} ${tmp}
1053 ${mv} ${tmp} ${inc}
1054 squeeze_em ${lib} ${tmp}
1055 ${mv} ${tmp} ${lib}
1057 ${mv} ${h} ${tmp}
1058 printf '#ifndef _CONFIG_H\n# define _CONFIG_H\n' > ${h}
1059 ${cat} ${tmp} >> ${h}
1060 printf '#endif /* _CONFIG_H */\n' >> ${h}
1061 ${rm} -f ${tmp}
1063 # Create the real mk.mk
1064 ${rm} -rf ${tmp0}.* ${tmp0}*
1065 printf 'OBJ_SRC = ' >> ${mk}
1066 if nwantfeat AMALGAMATION; then
1067 echo *.c >> ${mk}
1068 echo 'OBJ_DEP =' >> ${mk}
1069 else
1070 j=`echo "${src}" | sed 's/^.\///'`
1071 echo "${j}" >> ${mk}
1072 printf 'OBJ_DEP = main.c ' >> ${mk}
1073 printf '#define _MAIN_SOURCE\n' >> ${src}
1074 printf '#include "nail.h"\n#include "main.c"\n' >> ${src}
1075 for i in *.c; do
1076 if [ "${i}" = "${j}" ] || [ "${i}" = main.c ]; then
1077 continue
1079 printf "${i} " >> ${mk}
1080 printf "#include \"${i}\"\n" >> ${src}
1081 done
1082 echo >> ${mk}
1085 echo "LIBS = `${cat} ${lib}`" >> ${mk}
1086 echo "INCLUDES = `${cat} ${inc}`" >> ${mk}
1087 echo >> ${mk}
1088 ${cat} ./mk-mk.in >> ${mk}
1090 ## Finished! ##
1092 ${cat} > ${tmp2}.c << \!
1093 #include "config.h"
1094 #ifdef HAVE_NL_LANGINFO
1095 #include <langinfo.h>
1096 #endif
1098 :The following optional features are enabled:
1099 #ifdef HAVE_ICONV
1100 : + Character set conversion using iconv()
1101 #endif
1102 #ifdef HAVE_SETLOCALE
1103 : + Locale support: Printable characters depend on the environment
1104 # if defined HAVE_MBTOWC && defined HAVE_WCTYPE_H
1105 : + Multibyte character support
1106 # endif
1107 # if defined HAVE_NL_LANGINFO && defined CODESET
1108 : + Automatic detection of terminal character set
1109 # endif
1110 #endif
1111 #ifdef HAVE_SOCKETS
1112 : + Network support
1113 #endif
1114 #ifdef HAVE_IPV6
1115 : + Support for Internet Protocol v6 (IPv6)
1116 #endif
1117 #ifdef HAVE_OPENSSL
1118 : + S/MIME and SSL/TLS using OpenSSL
1119 #endif
1120 #ifdef HAVE_IMAP
1121 : + IMAP protocol
1122 #endif
1123 #ifdef HAVE_GSSAPI
1124 : + IMAP GSSAPI authentication
1125 #endif
1126 #ifdef HAVE_POP3
1127 : + POP3 protocol
1128 #endif
1129 #ifdef HAVE_SMTP
1130 : + SMTP protocol
1131 #endif
1132 #ifdef HAVE_SPAM
1133 : + Interaction with spam filters
1134 #endif
1135 #ifdef HAVE_IDNA
1136 : + IDNA (internationalized domain names for applications) support
1137 #endif
1138 #if defined HAVE_READLINE || defined HAVE_EDITLINE || defined HAVE_NCL
1139 : + Command line editing
1140 # ifdef HAVE_TABEXPAND
1141 : + + Tabulator expansion
1142 # endif
1143 # ifdef HAVE_HISTORY
1144 : + + History management
1145 # endif
1146 #endif
1147 #ifdef HAVE_QUOTE_FOLD
1148 : + Extended *quote-fold*ing
1149 #endif
1151 :The following optional features are disabled:
1152 #ifndef HAVE_ICONV
1153 : - Character set conversion using iconv()
1154 #endif
1155 #ifndef HAVE_SETLOCALE
1156 : - Locale support: Only ASCII characters are recognized
1157 #endif
1158 #if ! defined HAVE_SETLOCALE || ! defined HAVE_MBTOWC || !defined HAVE_WCTYPE_H
1159 : - Multibyte character support
1160 #endif
1161 #if ! defined HAVE_SETLOCALE || ! defined HAVE_NL_LANGINFO || ! defined CODESET
1162 : - Automatic detection of terminal character set
1163 #endif
1164 #ifndef HAVE_SOCKETS
1165 : - Network support
1166 #endif
1167 #ifndef HAVE_IPV6
1168 : - Support for Internet Protocol v6 (IPv6)
1169 #endif
1170 #if ! defined HAVE_SSL
1171 : - SSL/TLS (network transport authentication and encryption)
1172 #endif
1173 #ifndef HAVE_IMAP
1174 : - IMAP protocol
1175 #endif
1176 #ifndef HAVE_GSSAPI
1177 : - IMAP GSSAPI authentication
1178 #endif
1179 #ifndef HAVE_POP3
1180 : - POP3 protocol
1181 #endif
1182 #ifndef HAVE_SMTP
1183 : - SMTP protocol
1184 #endif
1185 #ifndef HAVE_SPAM
1186 : - Interaction with spam filters
1187 #endif
1188 #ifndef HAVE_IDNA
1189 : - IDNA (internationalized domain names for applications) support
1190 #endif
1191 #if !defined HAVE_READLINE && !defined HAVE_EDITLINE && !defined HAVE_NCL
1192 : - Command line editing and history
1193 #endif
1194 #ifndef HAVE_QUOTE_FOLD
1195 : - Extended *quote-fold*ing
1196 #endif
1198 :Remarks:
1199 #ifndef HAVE_SNPRINTF
1200 : . The function snprintf() could not be found. mailx will be compiled to use
1201 : sprintf() instead. This might overflow buffers if input values are larger
1202 : than expected. Use the resulting binary with care or update your system
1203 : environment and start the configuration process again.
1204 #endif
1205 #ifndef HAVE_FCHDIR
1206 : . The function fchdir() could not be found. mailx will be compiled to use
1207 : chdir() instead. This is not a problem unless the current working
1208 : directory of mailx is moved while the IMAP cache is used.
1209 #endif
1210 #ifndef HAVE_GETOPT
1211 : . Using a minimal builtin POSIX-like getopt()
1212 #endif
1213 #ifdef HAVE_DEBUG
1214 : . Debug enabled binary: not meant to be used by end-users: THANKS!
1215 #endif
1219 ${make} -f ${makefile} ${tmp2}.x
1220 < ${tmp2}.x >&5 ${sed} -e '/^[^:]/d; /^$/d; s/^://'
1222 # vim:set fenc=utf-8:s-it-mode