Offer a simple coloured display..
[s-mailx.git] / mk-conf.sh
blobf79bb0714426c90a84e861d010e15f49c0b4ed4c
1 #!/bin/sh -
2 #@ Please see `INSTALL' and `conf.rc' instead.
4 LC_ALL=C
5 export LC_ALL
7 # Predefined CONFIG= urations take precedence over anything else
8 if [ -n "${CONFIG}" ]; then
9 case ${CONFIG} in
10 MINIMAL)
11 WANT_SOCKETS=0
12 WANT_IDNA=0
13 WANT_READLINE=0 WANT_EDITLINE=0 WANT_NCL=0
14 WANT_REGEX=0
15 WANT_SPAM=0
16 WANT_DOCSTRINGS=0
17 WANT_QUOTE_FOLD=0
18 WANT_COLOUR=0
20 MEDIUM)
21 WANT_SOCKETS=0
22 WANT_IDNA=0
23 WANT_READLINE=0 WANT_EDITLINE=0
24 WANT_REGEX=0
25 WANT_SPAM=0
26 WANT_QUOTE_FOLD=0
27 WANT_COLOUR=0
29 NETSEND)
30 WANT_IMAP=0
31 WANT_POP3=0
32 WANT_READLINE=0 WANT_EDITLINE=0
33 WANT_REGEX=0
34 WANT_SPAM=0
35 WANT_QUOTE_FOLD=0
36 WANT_COLOUR=0
39 echo >&2 "Unknown CONFIG= setting: ${CONFIG}"
40 echo >&2 'Possible values: MINIMAL, MEDIUM, NETSEND'
41 exit 1
42 esac
45 # Inter-relationships
46 option_update() {
47 if nwantfeat SOCKETS; then
48 WANT_IPV6=0 WANT_SSL=0
49 WANT_IMAP=0 WANT_GSSAPI=0 WANT_POP3=0 WANT_SMTP=0
51 if nwantfeat IMAP && nwantfeat POP3 && nwantfeat SMTP; then
52 WANT_SOCKETS=0 WANT_IPV6=0 WANT_SSL=0
54 if nwantfeat IMAP; then
55 WANT_GSSAPI=0
57 # If we don't need MD5 except for producing boundary and message-id strings,
58 # leave it off, plain old srand(3) should be enough for that purpose.
59 if nwantfeat SOCKETS; then
60 WANT_MD5=0
62 if wantfeat DEBUG; then
63 WANT_NOALLOCA=1
67 # Check out compiler ($CC) and -flags ($CFLAGS)
68 compiler_flags() {
69 i=`uname -s`
70 _CFLAGS=
72 # $CC is overwritten when empty or a default "cc", even without WANT_AUTOCC
73 if [ -z "${CC}" ] || [ "${CC}" = cc ]; then
74 _CFLAGS=
75 if { CC="`command -v clang`"; }; then
77 elif { CC="`command -v gcc`"; }; then
79 elif { CC="`command -v c89`"; }; then
80 [ "${i}" = UnixWare ] && _CFLAGS='-v -O'
81 elif { CC="`command -v c99`"; }; then
83 else
84 echo >&2 'ERROR'
85 echo >&2 ' I cannot find a compiler!'
86 echo >&2 ' Neither of clang(1), gcc(1), c89(1) and c99(1).'
87 echo >&2 ' Please set the CC environment variable, maybe CFLAGS also.'
88 exit 1
91 export CC
93 ccver=`${CC} --version 2>/dev/null`
94 stackprot=no
95 if { i=$ccver; echo "${i}"; } | ${grep} -q -i -e gcc -e clang; then
96 #if echo "${i}" | ${grep} -q -i -e gcc -e 'clang version 1'; then
97 stackprot=yes
98 _CFLAGS='-std=c89 -O2'
99 _CFLAGS="${_CFLAGS} -Wall -Wextra -pedantic"
100 _CFLAGS="${_CFLAGS} -fno-unwind-tables -fno-asynchronous-unwind-tables"
101 _CFLAGS="${_CFLAGS} -fstrict-aliasing"
102 _CFLAGS="${_CFLAGS} -Wbad-function-cast -Wcast-align -Wcast-qual"
103 _CFLAGS="${_CFLAGS} -Winit-self -Wshadow -Wunused -Wwrite-strings"
104 if { i=$ccver; echo "${i}"; } | ${grep} -q -e 'clang version 1'; then
106 else
107 _CFLAGS="${_CFLAGS} -fstrict-overflow -Wstrict-overflow=5"
108 if wantfeat AMALGAMATION && nwantfeat DEBUG; then
109 _CFLAGS="${_CFLAGS} -Wno-unused-function"
111 if { i=$ccver; echo "${i}"; } | ${grep} -q -i -e clang; then
112 _CFLAGS="${_CFLAGS} -Wno-unused-result" # TODO handle the right way
115 _CFLAGS="${_CFLAGS} -Wno-long-long" # ISO C89 has no 'long long'...
116 # elif { i=$ccver; echo "${i}"; } | ${grep} -q -i -e clang; then
117 # stackprot=yes
118 # _CFLAGS='-std=c89 -O3 -g -Weverything -Wno-long-long'
119 elif [ -z "${_CFLAGS}" ]; then
120 _CFLAGS=-O1
123 if nwantfeat DEBUG; then
124 _CFLAGS="${_CFLAGS} -DNDEBUG"
125 else
126 _CFLAGS="${_CFLAGS} -g";
127 if [ "${stackprot}" = yes ]; then
128 _CFLAGS="${_CFLAGS} -fstack-protector-all "
129 _CFLAGS="${_CFLAGS} -Wstack-protector -D_FORTIFY_SOURCE=2"
132 _CFLAGS="${_CFLAGS} ${ADDCFLAGS}"
133 _LDFLAGS="${_LDFLAGS} ${ADDLDFLAGS}" # XXX -Wl,--sort-common,[-O1]
134 export _CFLAGS _LDFLAGS
136 # $CFLAGS and $LDFLAGS are only overwritten if explicitly wanted
137 if wantfeat AUTOCC; then
138 CFLAGS=$_CFLAGS
139 LDFLAGS=$_LDFLAGS
140 export CFLAGS LDFLAGS
144 ## -- >8 -- 8< -- ##
146 ## Notes:
147 ## - Heirloom sh(1) (and same origin) have problems with ': >' redirection,
148 ## so use "printf '' >" instead
149 ## - Heirloom sh(1) and maybe more execute loops with redirection in a subshell
150 ## (but don't export eval's from within), therefore we need to (re)include
151 ## variable assignments at toplevel instead (via reading temporary files)
153 ## First of all, create new configuration and check wether it changed ##
155 conf=./conf.rc
156 lst=./config.lst
157 h=./config.h
158 mk=./mk.mk
160 newlst=./config.lst-new
161 newmk=./config.mk-new
162 newh=./config.h-new
163 tmp0=___tmp
164 tmp=./${tmp0}1$$
166 # We need some standard utilities
167 unset -f command
168 check_tool() {
169 n=$1 i=$2 opt=${3:-0}
170 if type "${i}" >/dev/null 2>&1; then
171 eval ${n}=${i}
172 return 1
174 if [ ${opt} -eq 0 ]; then
175 echo >&2 "ERROR: no trace of the utility \`${n}'"
176 exit 1
178 return 0
181 # Check those tools right now that we need before including ${conf}
182 check_tool rm "${rm:-`command -pv rm`}"
183 check_tool sed "${sed:-`command -pv sed`}"
185 # Only incorporate what wasn't overwritten from command line / CONFIG
186 trap "${rm} -f ${tmp}; exit" 1 2 15
187 trap "${rm} -f ${tmp}" 0
188 ${rm} -f ${tmp}
190 < ${conf} ${sed} -e '/^[ \t]*#/d' -e '/^$/d' -e 's/[ \t]*$//' |
191 while read line; do
192 i=`echo ${line} | ${sed} -e 's/=.*$//'`
193 eval j=\$${i} jx=\${${i}+x}
194 if [ -n "${j}" ] || [ "${jx}" = x ]; then
195 line="${i}=\"${j}\""
197 echo ${line}
198 done > ${tmp}
199 . ./${tmp}
201 check_tool awk "${awk:-`command -pv awk`}"
202 check_tool cat "${cat:-`command -pv cat`}"
203 check_tool chmod "${chmod:-`command -pv chmod`}"
204 check_tool cp "${cp:-`command -pv cp`}"
205 check_tool cmp "${cmp:-`command -pv cmp`}"
206 check_tool grep "${grep:-`command -pv grep`}"
207 check_tool mkdir "${mkdir:-`command -pv mkdir`}"
208 check_tool mv "${mv:-`command -pv mv`}"
209 # rm(1), sed(1) above
210 check_tool tee "${tee:-`command -pv tee`}"
212 check_tool make "${MAKE:-`command -pv make`}"
213 check_tool strip "${STRIP:-`command -pv strip`}" 1
214 HAVE_STRIP=${?}
216 wantfeat() {
217 eval i=\$WANT_${1}
218 [ "${i}" = "1" ]
220 nwantfeat() {
221 eval i=\$WANT_${1}
222 [ "${i}" != "1" ]
225 option_update
227 # (No function since some shells loose non-exported variables in traps)
228 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}; exit" 1 2 15
229 trap "${rm} -f ${tmp} ${newlst} ${newmk} ${newh}" 0
230 ${rm} -f ${newlst} ${newmk} ${newh}
232 # (Could: use FD redirection, add eval(1) and don't re-'. ./${newlst}')
233 while read line; do
234 i=`echo ${line} | ${sed} -e 's/=.*$//'`
235 eval j=\$${i}
236 if [ -z "${j}" ] || [ "${j}" = 0 ]; then
237 printf "/*#define ${i}*/\n" >> ${newh}
238 elif [ "${j}" = 1 ]; then
239 printf "#define ${i}\n" >> ${newh}
240 else
241 printf "#define ${i} \"${j}\"\n" >> ${newh}
243 printf "${i} = ${j}\n" >> ${newmk}
244 printf "${i}=\"${j}\"\n"
245 done < ${tmp} > ${newlst}
246 . ./${newlst}
248 printf "#define UAGENT \"${SID}${NAIL}\"\n" >> ${newh}
249 printf "UAGENT = ${SID}${NAIL}\n" >> ${newmk}
251 compiler_flags
253 printf "CC = ${CC}\n" >> ${newmk}
254 printf "_CFLAGS = ${_CFLAGS}\nCFLAGS = ${CFLAGS}\n" >> ${newmk}
255 printf "_LDFLAGS = ${_LDFLAGS}\nLDFLAGS = ${LDFLAGS}\n" >> ${newmk}
256 printf "AWK = ${awk}\nCMP = ${cmp}\nCHMOD = ${chmod}\nCP = ${cp}\n" >> ${newmk}
257 printf "MKDIR = ${mkdir}\nRM = ${rm}\nSED = ${sed}\n" >> ${newmk}
258 printf "STRIP = ${strip}\nHAVE_STRIP = ${HAVE_STRIP}\n" >> ${newmk}
259 # (We include the cc(1)/ld(1) environment only for update detection..)
260 printf "CC=\"${CC}\"\n" >> ${newlst}
261 printf "_CFLAGS=\"${_CFLAGS}\"\nCFLAGS=\"${CFLAGS}\"\n" >> ${newlst}
262 printf "_LDFLAGS=\"${_LDFLAGS}\"\nLDFLAGS=\"${LDFLAGS}\"\n" >> ${newlst}
263 printf "AWK=${awk}\nCMP=${cmp}\nCHMOD=${chmod}\nCP=${cp}\n" >> ${newlst}
264 printf "MKDIR=${mkdir}\nRM=${rm}\nSED=${sed}\n" >> ${newlst}
265 printf "STRIP=${strip}\nHAVE_STRIP=${HAVE_STRIP}\n" >> ${newlst}
267 if [ -f ${lst} ] && ${cmp} ${newlst} ${lst} >/dev/null 2>&1; then
268 exit 0
270 [ -f ${lst} ] && echo 'configuration updated..' || echo 'shiny configuration..'
272 ${mv} -f ${newlst} ${lst}
273 ${mv} -f ${newh} ${h}
274 ${mv} -f ${newmk} ${mk}
276 ## Compile and link checking ##
278 tmp2=./${tmp0}2$$
279 tmp3=./${tmp0}3$$
280 log=./config.log
281 lib=./config.lib
282 inc=./config.inc
283 src=./config.c
284 makefile=./config.mk
286 # (No function since some shells loose non-exported variables in traps)
287 trap "${rm} -f ${lst} ${h} ${mk} ${lib} ${inc} ${src} ${makefile}; exit" 1 2 15
288 trap "${rm} -rf ${tmp0}.* ${tmp0}* ${makefile}" 0
290 exec 5>&2 > ${log} 2>&1
291 printf '' > ${lib}
292 printf '' > ${inc}
293 # ${src} is only created if WANT_AMALGAMATION
294 ${rm} -f ${src}
295 ${cat} > ${makefile} << \!
296 .SUFFIXES: .o .c .x .y
297 .c.o:
298 $(CC) $(XINCS) -c $<
299 .c.x:
300 $(CC) $(XINCS) -E $< >$@
302 $(CC) $(XINCS) -o $@ $< $(XLIBS)
303 .y: ;
306 msg() {
307 fmt=$1
309 shift
310 printf "*** ${fmt}\\n" "${@}"
311 printf "${fmt}" "${@}" >&5
314 _check_preface() {
315 variable=$1 topic=$2 define=$3
317 echo '**********'
318 msg "checking ${topic} ... "
319 echo "/* checked ${topic} */" >> ${h}
320 ${rm} -f ${tmp} ${tmp}.o
321 echo '*** test program is'
322 ${tee} ${tmp}.c
323 #echo '*** the preprocessor generates'
324 #${make} -f ${makefile} ${tmp}.x
325 #${cat} ${tmp}.x
326 echo '*** results are'
329 compile_check() {
330 variable=$1 topic=$2 define=$3
332 _check_preface "${variable}" "${topic}" "${define}"
334 if ${make} -f ${makefile} XINCS="${INCS}" ./${tmp}.o &&
335 [ -f ./${tmp}.o ]; then
336 msg "yes\\n"
337 echo "${define}" >> ${h}
338 eval have_${variable}=yes
339 return 0
340 else
341 echo "/* ${define} */" >> ${h}
342 msg "no\\n"
343 eval unset have_${variable}
344 return 1
348 _link_mayrun() {
349 run=$1 variable=$2 topic=$3 define=$4 libs=$5 incs=$6
351 _check_preface "${variable}" "${topic}" "${define}"
353 if ${make} -f ${makefile} XINCS="${INCS} ${incs}" \
354 XLIBS="${LIBS} ${libs}" ./${tmp} &&
355 [ -f ./${tmp} ] &&
356 { [ ${run} -eq 0 ] || ./${tmp}; }; then
357 echo "*** adding INCS<${incs}> LIBS<${libs}>"
358 msg "yes\\n"
359 echo "${define}" >> ${h}
360 LIBS="${LIBS} ${libs}"
361 echo "${libs}" >> ${lib}
362 INCS="${INCS} ${incs}"
363 echo "${incs}" >> ${inc}
364 eval have_${variable}=yes
365 return 0
366 else
367 msg "no\\n"
368 echo "/* ${define} */" >> ${h}
369 eval unset have_${variable}
370 return 1
374 link_check() {
375 _link_mayrun 0 "${1}" "${2}" "${3}" "${4}" "${5}"
378 run_check() {
379 _link_mayrun 1 "${1}" "${2}" "${3}" "${4}" "${5}"
382 # Build a basic set of INCS and LIBS according to user environment.
383 # On pkgsrc(7) systems automatically add /usr/pkg/*
384 if [ -n "${C_INCLUDE_PATH}" ]; then
385 i=${IFS}
386 IFS=:
387 set -- ${C_INCLUDE_PATH}
388 IFS=${i}
389 # for i; do -- new in POSIX Issue 7 + TC1
390 for i
392 [ "${i}" = '/usr/pkg/include' ] && continue
393 INCS="${INCS} -I${i}"
394 done
396 [ -d /usr/pkg/include ] && INCS="${INCS} -I/usr/pkg/include"
397 echo "${INCS}" >> ${inc}
399 if [ -n "${LD_LIBRARY_PATH}" ]; then
400 i=${IFS}
401 IFS=:
402 set -- ${LD_LIBRARY_PATH}
403 IFS=${i}
404 # for i; do -- new in POSIX Issue 7 + TC1
405 for i
407 [ "${i}" = '/usr/pkg/lib' ] && continue
408 LIBS="${LIBS} -L${i}"
409 done
411 [ -d /usr/pkg/lib ] && LIBS="${LIBS} -L/usr/pkg/lib"
412 echo "${LIBS}" >> ${lib}
416 # Better set _GNU_SOURCE (if we are on Linux only?); 'surprised it did without
417 echo '#define _GNU_SOURCE' >> ${h}
419 link_check hello 'if a hello world program can be built' << \! || {\
420 echo >&5 'This oooops is most certainly not related to me.';\
421 echo >&5 "Read the file ${log} and check your compiler environment.";\
422 ${rm} -f ${lst} ${h} ${mk};\
423 exit 1;\
425 #include <stdio.h>
427 int main(int argc, char *argv[])
429 (void)argc;
430 (void)argv;
431 puts("hello world");
432 return 0;
436 link_check termios 'for termios.h and tc*() family' << \! || {\
437 echo >&5 'We require termios.h and the tc*() family of functions.';\
438 echo >&5 "That much Unix we indulge ourselfs.";\
439 ${rm} -f ${lst} ${h} ${mk};\
440 exit 1;\
442 #include <termios.h>
443 int main(void)
445 struct termios tios;
446 tcgetattr(0, &tios);
447 tcsetattr(0, TCSADRAIN | TCSAFLUSH, &tios);
448 return 0;
452 link_check snprintf 'for snprintf()' '#define HAVE_SNPRINTF' << \!
453 #include <stdio.h>
454 int main(void)
456 char b[20];
457 snprintf(b, sizeof b, "%s", "string");
458 return 0;
462 link_check putc_unlocked 'for putc_unlocked()' '#define HAVE_PUTC_UNLOCKED' <<\!
463 #include <stdio.h>
464 int main(void)
466 putc_unlocked('@', stdout);
467 return 0;
471 link_check fchdir 'for fchdir()' '#define HAVE_FCHDIR' << \!
472 #include <unistd.h>
473 int main(void)
475 fchdir(0);
476 return 0;
480 link_check mmap 'for mmap()' '#define HAVE_MMAP' << \!
481 #include <sys/types.h>
482 #include <sys/mman.h>
483 int main(void)
485 mmap(0, 0, 0, 0, 0, 0);
486 return 0;
490 link_check mremap 'for mremap()' '#define HAVE_MREMAP' << \!
491 #include <sys/types.h>
492 #include <sys/mman.h>
493 int main(void)
495 mremap(0, 0, 0, MREMAP_MAYMOVE);
496 return 0;
500 link_check setlocale 'for setlocale()' '#define HAVE_SETLOCALE' << \!
501 #include <locale.h>
502 int main(void)
504 setlocale(LC_ALL, "");
505 return 0;
509 if [ "${have_setlocale}" = yes ]; then
510 link_check c90amend1 'for ISO/IEC 9899:1990/Amendment 1:1995' \
511 '#define HAVE_C90AMEND1' << \!
512 #include <limits.h>
513 #include <stdlib.h>
514 #include <wchar.h>
515 #include <wctype.h>
516 int main(void)
518 char mbb[MB_LEN_MAX + 1];
519 wchar_t wc;
520 iswprint(L'c');
521 towupper(L'c');
522 mbtowc(&wc, "x", 1);
523 mbrtowc(&wc, "x", 1, NULL);
524 (void)wctomb(mbb, wc);
525 return (mblen("\0", 1) == 0);
529 if [ "${have_c90amend1}" = yes ]; then
530 link_check wcwidth 'for wcwidth()' '#define HAVE_WCWIDTH' << \!
531 #include <wchar.h>
532 int main(void)
534 wcwidth(L'c');
535 return 0;
540 link_check nl_langinfo 'for nl_langinfo()' '#define HAVE_NL_LANGINFO' << \!
541 #include <langinfo.h>
542 #include <stdlib.h>
543 int main(void)
545 nl_langinfo(DAY_1);
546 return (nl_langinfo(CODESET) == NULL);
549 fi # have_setlocale
551 link_check mkstemp 'for mkstemp()' '#define HAVE_MKSTEMP' << \!
552 #include <stdlib.h>
553 int main(void)
555 mkstemp("x");
556 return 0;
560 # Note: run_check, thus we also get only the desired implementation...
561 run_check realpath 'for realpath()' '#define HAVE_REALPATH' << \!
562 #include <stdlib.h>
563 int main(void)
565 char *x = realpath(".", NULL), *y = realpath("/", NULL);
566 return (x != NULL && y != NULL) ? 0 : 1;
570 link_check wordexp 'for wordexp()' '#define HAVE_WORDEXP' << \!
571 #include <wordexp.h>
572 int main(void)
574 wordexp((char *)0, (wordexp_t *)0, 0);
575 return 0;
581 if wantfeat DEBUG; then
582 echo '#define HAVE_DEBUG' >> ${h}
585 if wantfeat AMALGAMATION; then
586 echo '#define HAVE_AMALGAMATION' >> ${h}
589 if nwantfeat NOALLOCA; then
590 # Due to NetBSD PR lib/47120 it seems best not to use non-cc-builtin
591 # versions of alloca(3) since modern compilers just can't be trusted
592 # not to overoptimize and silently break some code
593 link_check alloca 'for __builtin_alloca()' \
594 '#define HAVE_ALLOCA __builtin_alloca' << \!
595 int main(void)
597 void *vp = __builtin_alloca(1);
598 return (!! vp);
603 if nwantfeat NOGETOPT; then
604 link_check getopt 'for getopt()' '#define HAVE_GETOPT' << \!
605 #include <unistd.h>
606 int main(int argc, char **argv)
608 #if defined __GLIBC__ || defined __linux__
609 Argument and option reordering is not a desired feature.
610 #else
611 getopt(argc, argv, "oPt");
612 #endif
613 return (((long)optarg + optind) & 0x7F);
620 if wantfeat ICONV; then
621 ${cat} > ${tmp2}.c << \!
622 #include <iconv.h>
623 int main(void)
625 iconv_t id;
627 id = iconv_open("foo", "bar");
628 return 0;
631 < ${tmp2}.c link_check iconv 'for iconv functionality' \
632 '#define HAVE_ICONV' ||
633 < ${tmp2}.c link_check iconv \
634 'for iconv functionality in libiconv' \
635 '#define HAVE_ICONV' '-liconv'
636 else
637 echo '/* WANT_ICONV=0 */' >> ${h}
638 fi # wantfeat ICONV
640 if wantfeat SOCKETS; then
641 compile_check arpa_inet_h 'for <arpa/inet.h>' \
642 '#define HAVE_ARPA_INET_H' << \!
643 #include "config.h"
644 #include <sys/types.h>
645 #include <sys/socket.h>
646 #include <netdb.h>
647 #include <netinet/in.h>
648 #include <arpa/inet.h>
651 ${cat} > ${tmp2}.c << \!
652 #include "config.h"
653 #include <sys/types.h>
654 #include <sys/socket.h>
655 #include <netdb.h>
656 #include <netinet/in.h>
657 #ifdef HAVE_ARPA_INET_H
658 #include <arpa/inet.h>
659 #endif
661 int main(void)
663 struct sockaddr s;
664 socket(AF_INET, SOCK_STREAM, 0);
665 connect(0, &s, 0);
666 gethostbyname("foo");
667 return 0;
671 < ${tmp2}.c link_check sockets 'for sockets in libc' \
672 '#define HAVE_SOCKETS' ||
673 < ${tmp2}.c link_check sockets 'for sockets in libnsl' \
674 '#define HAVE_SOCKETS' '-lnsl' ||
675 < ${tmp2}.c link_check sockets \
676 'for sockets in libsocket and libnsl' \
677 '#define HAVE_SOCKETS' '-lsocket -lnsl' ||
678 WANT_SOCKETS=0
680 # XXX Shouldn't it be a hard error if there is no socket support, then?
681 option_update
682 else
683 echo '/* WANT_SOCKETS=0 */' >> ${h}
684 fi # wantfeat SOCKETS
686 wantfeat SOCKETS &&
687 link_check setsockopt 'for setsockopt()' '#define HAVE_SETSOCKOPT' << \!
688 #include <sys/socket.h>
689 #include <stdlib.h>
690 int main(void)
692 int sockfd = 3;
693 setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0);
694 return 0;
698 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
699 link_check so_sndtimeo 'for SO_SNDTIMEO' '#define HAVE_SO_SNDTIMEO' << \!
700 #include <sys/socket.h>
701 #include <stdlib.h>
702 int main(void)
704 struct timeval tv;
705 int sockfd = 3;
706 tv.tv_sec = 42;
707 tv.tv_usec = 21;
708 setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
709 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
710 return 0;
714 wantfeat SOCKETS && [ -n "${have_setsockopt}" ] &&
715 link_check so_linger 'for SO_LINGER' '#define HAVE_SO_LINGER' << \!
716 #include <sys/socket.h>
717 #include <stdlib.h>
718 int main(void)
720 struct linger li;
721 int sockfd = 3;
722 li.l_onoff = 1;
723 li.l_linger = 42;
724 setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &li, sizeof li);
725 return 0;
729 if wantfeat IPV6; then
730 link_check ipv6 'for IPv6 functionality' '#define HAVE_IPV6' << \!
731 #include "config.h"
732 #include <sys/types.h>
733 #include <sys/socket.h>
734 #include <netdb.h>
735 #include <netinet/in.h>
736 #ifdef HAVE_ARPA_INET_H
737 #include <arpa/inet.h>
738 #endif
740 int main(void)
742 struct addrinfo a, *ap;
743 getaddrinfo("foo", "0", &a, &ap);
744 return 0;
747 else
748 echo '/* WANT_IPV6=0 */' >> ${h}
749 fi # wantfeat IPV6
751 if wantfeat IMAP; then
752 echo '#define HAVE_IMAP' >> ${h}
753 else
754 echo '/* WANT_IMAP=0 */' >> ${h}
757 if wantfeat POP3; then
758 echo '#define HAVE_POP3' >> ${h}
759 else
760 echo '/* WANT_POP3=0 */' >> ${h}
763 if wantfeat SMTP; then
764 echo '#define HAVE_SMTP' >> ${h}
765 else
766 echo '/* WANT_SMTP=0 */' >> ${h}
769 if wantfeat SSL; then
770 link_check openssl 'for sufficiently recent OpenSSL' \
771 '#define HAVE_SSL
772 #define HAVE_OPENSSL' '-lssl -lcrypto' << \!
773 #include <openssl/ssl.h>
774 #include <openssl/err.h>
775 #include <openssl/x509v3.h>
776 #include <openssl/x509.h>
777 #include <openssl/rand.h>
779 #if defined OPENSSL_NO_SSL2 && defined OPENSSL_NO_SSL3 &&\
780 defined OPENSSL_NO_TLS1
781 # error We need one of (SSLv2 and) SSLv3 and TLS1.
782 #endif
784 int main(void)
786 SSLv23_client_method();
787 #ifndef OPENSSL_NO_SSL3
788 SSLv3_client_method();
789 #endif
790 #ifndef OPENSSL_NO_TLS1
791 TLSv1_client_method();
792 # ifdef TLS1_1_VERSION
793 TLSv1_1_client_method();
794 # endif
795 # ifdef TLS1_2_VERSION
796 TLSv1_2_client_method();
797 # endif
798 #endif
799 PEM_read_PrivateKey(0, 0, 0, 0);
800 return 0;
804 if [ "${have_openssl}" = 'yes' ]; then
805 compile_check stack_of 'for OpenSSL STACK_OF()' \
806 '#define HAVE_STACK_OF' << \!
807 #include <openssl/ssl.h>
808 #include <openssl/err.h>
809 #include <openssl/x509v3.h>
810 #include <openssl/x509.h>
811 #include <openssl/rand.h>
813 int main(void)
815 STACK_OF(GENERAL_NAME) *gens = NULL;
816 printf("%p", gens); /* to make it used */
817 return 0;
821 run_check openssl_md5 'for MD5 digest in OpenSSL' \
822 '#define HAVE_OPENSSL_MD5' << \!
823 #include <string.h>
824 #include <openssl/md5.h>
826 int main(void)
828 char const dat[] = "abrakadabrafidibus";
829 char dig[16], hex[16 * 2];
830 MD5_CTX ctx;
831 size_t i, j;
833 memset(dig, 0, sizeof(dig));
834 memset(hex, 0, sizeof(hex));
835 MD5_Init(&ctx);
836 MD5_Update(&ctx, dat, sizeof(dat) - 1);
837 MD5_Final(dig, &ctx);
839 #define hexchar(n) ((n)>9 ? (n)-10+'a' : (n)+'0')
840 for (i = 0; i < sizeof(hex) / 2; i++) {
841 j = i << 1;
842 hex[j] = hexchar((dig[i] & 0xf0) >> 4);
843 hex[++j] = hexchar(dig[i] & 0x0f);
845 return !!memcmp("6d7d0a3d949da2e96f2aa010f65d8326", hex, sizeof(hex));
850 else
851 echo '/* WANT_SSL=0 */' >> ${h}
852 fi # wantfeat SSL
854 if wantfeat GSSAPI; then
855 ${cat} > ${tmp2}.c << \!
856 #include <gssapi/gssapi.h>
858 int main(void)
860 gss_import_name(0, 0, GSS_C_NT_HOSTBASED_SERVICE, 0);
861 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
862 return 0;
865 ${sed} -e '1s/gssapi\///' < ${tmp2}.c > ${tmp3}.c
867 if command -v krb5-config >/dev/null 2>&1; then
868 i=`command -v krb5-config`
869 GSSAPI_LIBS="`CFLAGS= ${i} --libs gssapi`"
870 GSSAPI_INCS="`CFLAGS= ${i} --cflags`"
871 i='for GSSAPI via krb5-config(1)'
872 else
873 GSSAPI_LIBS='-lgssapi'
874 GSSAPI_INCS=
875 i='for GSSAPI in gssapi/gssapi.h, libgssapi'
877 < ${tmp2}.c link_check gssapi \
878 "${i}" '#define HAVE_GSSAPI' \
879 "${GSSAPI_LIBS}" "${GSSAPI_INCS}" ||\
880 < ${tmp3}.c link_check gssapi \
881 'for GSSAPI in gssapi.h, libgssapi' \
882 '#define HAVE_GSSAPI
883 #define GSSAPI_REG_INCLUDE' \
884 '-lgssapi' ||\
885 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgssapi_krb5' \
886 '#define HAVE_GSSAPI' \
887 '-lgssapi_krb5' ||\
888 < ${tmp3}.c link_check gssapi \
889 'for GSSAPI in libgssapi, OpenBSD-style (pre 5.3)' \
890 '#define HAVE_GSSAPI
891 #define GSSAPI_REG_INCLUDE' \
892 '-lgssapi -lkrb5 -lcrypto' \
893 '-I/usr/include/kerberosV' ||\
894 < ${tmp2}.c link_check gssapi 'for GSSAPI in libgss' \
895 '#define HAVE_GSSAPI' \
896 '-lgss' ||\
897 link_check gssapi 'for GSSAPI in libgssapi_krb5, old-style' \
898 '#define HAVE_GSSAPI
899 #define GSSAPI_OLD_STYLE' \
900 '-lgssapi_krb5' << \!
901 #include <gssapi/gssapi.h>
902 #include <gssapi/gssapi_generic.h>
904 int main(void)
906 gss_import_name(0, 0, gss_nt_service_name, 0);
907 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
908 return 0;
911 else
912 echo '/* WANT_GSSAPI=0 */' >> ${h}
913 fi # wantfeat GSSAPI
915 if wantfeat IDNA; then
916 link_check idna 'for GNU Libidn' '#define HAVE_IDNA' '-lidn' << \!
917 #include <idna.h>
918 #include <stringprep.h>
919 int main(void)
921 char *utf8, *idna_ascii, *idna_utf8;
922 utf8 = stringprep_locale_to_utf8("does.this.work");
923 if (idna_to_ascii_8z(utf8, &idna_ascii, IDNA_USE_STD3_ASCII_RULES)
924 != IDNA_SUCCESS)
925 return 1;
926 /* (Rather link check only here) */
927 idna_utf8 = stringprep_convert(idna_ascii, "UTF-8", "de_DE");
928 return 0;
931 else
932 echo '/* WANT_IDNA=0 */' >> ${h}
935 if wantfeat REGEX; then
936 link_check regex 'for regular expressions' '#define HAVE_REGEX' << \!
937 #include <regex.h>
938 #include <stdlib.h>
939 int main(void)
941 int status;
942 regex_t re;
943 if (regcomp(&re, ".*bsd", REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
944 return 1;
945 status = regexec(&re, "plan9", 0,NULL, 0);
946 regfree(&re);
947 return !(status == REG_NOMATCH);
950 else
951 echo '/* WANT_REGEX=0 */' >> ${h}
954 if wantfeat READLINE; then
955 __edrdlib() {
956 link_check readline "for readline(3) (${1})" \
957 '#define HAVE_READLINE' "${1}" << \!
958 #include <stdio.h>
959 #include <readline/history.h>
960 #include <readline/readline.h>
961 int main(void)
963 char *rl;
964 using_history();
965 read_history("");
966 stifle_history(242);
967 rl = readline("Enter a line:");
968 if (rl && *rl)
969 add_history(rl);
970 write_history("");
971 rl_extend_line_buffer(10);
972 rl_point = rl_end = 10;
973 rl_pre_input_hook = (rl_hook_func_t*)NULL;
974 rl_forced_update_display();
976 rl_free_line_state();
977 rl_cleanup_after_signal();
978 rl_reset_after_signal();
979 return 0;
984 __edrdlib -lreadline ||
985 __edrdlib '-lreadline -ltermcap'
986 [ -n "${have_readline}" ] && WANT_TABEXPAND=1
989 if wantfeat EDITLINE && [ -z "${have_readline}" ]; then
990 __edlib() {
991 link_check editline "for editline(3) (${1})" \
992 '#define HAVE_EDITLINE' "${1}" << \!
993 #include <histedit.h>
994 static char * getprompt(void) { return (char*)"ok"; }
995 int main(void)
997 HistEvent he;
998 EditLine *el_el = el_init("TEST", stdin, stdout, stderr);
999 History *el_hcom = history_init();
1000 history(el_hcom, &he, H_SETSIZE, 242);
1001 el_set(el_el, EL_SIGNAL, 0);
1002 el_set(el_el, EL_TERMINAL, NULL);
1003 el_set(el_el, EL_HIST, &history, el_hcom);
1004 el_set(el_el, EL_EDITOR, "emacs");
1005 el_set(el_el, EL_PROMPT, &getprompt);
1006 el_source(el_el, NULL);
1007 el_end(el_el);
1008 /* TODO add loader and addfn checks */
1009 history_end(el_hcom);
1010 return 0;
1015 __edlib -ledit ||
1016 __edlib '-ledit -ltermcap'
1017 [ -n "${have_editline}" ] && WANT_TABEXPAND=0
1020 if wantfeat NCL && [ -z "${have_editline}" ] && [ -z "${have_readline}" ] &&\
1021 [ -n "${have_c90amend1}" ]; then
1022 have_ncl=1
1023 echo '#define HAVE_NCL' >> ${h}
1024 else
1025 echo '/* WANT_{READLINE,EDITLINE,NCL}=0 */' >> ${h}
1028 if [ -n "${have_ncl}" ] || [ -n "${have_editline}" ] ||\
1029 [ -n "${have_readline}" ]; then
1030 have_cle=1
1033 if [ -n "${have_cle}" ] && wantfeat TABEXPAND; then
1034 echo '#define HAVE_TABEXPAND' >> ${h}
1035 else
1036 echo '/* WANT_TABEXPAND=0 */' >> ${h}
1039 if [ -n "${have_cle}" ] && wantfeat HISTORY; then
1040 echo '#define HAVE_HISTORY' >> ${h}
1041 else
1042 echo '/* WANT_HISTORY=0 */' >> ${h}
1045 if wantfeat SPAM; then
1046 echo '#define HAVE_SPAM' >> ${h}
1047 if command -v spamc >/dev/null 2>&1; then
1048 echo "#define SPAMC_PATH \"`command -v spamc`\"" >> ${h}
1050 else
1051 echo '/* WANT_SPAM=0 */' >> ${h}
1054 if wantfeat DOCSTRINGS; then
1055 echo '#define HAVE_DOCSTRINGS' >> ${h}
1056 else
1057 echo '/* WANT_DOCSTRINGS=0 */' >> ${h}
1060 if wantfeat QUOTE_FOLD &&\
1061 [ -n "${have_c90amend1}" ] && [ -n "${have_wcwidth}" ]; then
1062 echo '#define HAVE_QUOTE_FOLD' >> ${h}
1063 else
1064 echo '/* WANT_QUOTE_FOLD=0 */' >> ${h}
1067 if wantfeat COLOUR; then
1068 echo '#define HAVE_COLOUR' >> ${h}
1069 else
1070 echo '/* WANT_COLOUR=0 */' >> ${h}
1073 if wantfeat MD5; then
1074 echo '#define HAVE_MD5' >> ${h}
1075 else
1076 echo '/* WANT_MD5=0 */' >> ${h}
1079 ## Summarizing ##
1081 # Since we cat(1) the content of those to cc/"ld", convert them to single line
1082 squeeze_em() {
1083 < "${1}" > "${2}" ${awk} \
1084 'BEGIN {ORS = " "} /^[^#]/ {print} {next} END {ORS = ""; print "\n"}'
1086 ${rm} -f ${tmp}
1087 squeeze_em ${inc} ${tmp}
1088 ${mv} ${tmp} ${inc}
1089 squeeze_em ${lib} ${tmp}
1090 ${mv} ${tmp} ${lib}
1092 # config.h
1093 ${mv} ${h} ${tmp}
1094 printf '#ifndef _CONFIG_H\n# define _CONFIG_H\n' > ${h}
1095 ${cat} ${tmp} >> ${h}
1097 printf '\n/* The "feature string", for "simplicity" and lex.c */\n' >> ${h}
1098 printf '#ifdef _MAIN_SOURCE\n' >> ${h}
1099 printf '# ifdef HAVE_AMALGAMATION\nstatic\n# endif\n' >> ${h}
1100 printf 'char const features[] = "MIME"\n' >> ${h}
1101 printf '# ifdef HAVE_DOCSTRINGS\n ",DOCSTRINGS"\n# endif\n' >> ${h}
1102 printf '# ifdef HAVE_ICONV\n ",ICONV"\n# endif\n' >> ${h}
1103 printf '# ifdef HAVE_SETLOCALE\n ",LOCALES"\n# endif\n' >> ${h}
1104 printf '# ifdef HAVE_C90AMEND1\n ",MULTIBYTE CHARSETS"\n# endif\n' >> ${h}
1105 printf '# ifdef HAVE_NL_LANGINFO\n ",TERMINAL CHARSET"\n# endif\n' >> ${h}
1106 printf '# ifdef HAVE_SOCKETS\n ",NETWORK"\n# endif\n' >> ${h}
1107 printf '# ifdef HAVE_IPV6\n ",IPv6"\n# endif\n' >> ${h}
1108 printf '# ifdef HAVE_SSL\n ",S/MIME,SSL/TSL"\n# endif\n' >> ${h}
1109 printf '# ifdef HAVE_IMAP\n ",IMAP"\n# endif\n' >> ${h}
1110 printf '# ifdef HAVE_GSSAPI\n ",GSSAPI"\n# endif\n' >> ${h}
1111 printf '# ifdef HAVE_POP3\n ",POP3"\n# endif\n' >> ${h}
1112 printf '# ifdef HAVE_SMTP\n ",SMTP"\n# endif\n' >> ${h}
1113 printf '# ifdef HAVE_SPAM\n ",SPAM"\n# endif\n' >> ${h}
1114 printf '# ifdef HAVE_IDNA\n ",IDNA"\n# endif\n' >> ${h}
1115 printf '# ifdef HAVE_REGEX\n ",REGEX"\n# endif\n' >> ${h}
1116 printf '# ifdef HAVE_READLINE\n ",READLINE"\n# endif\n' >> ${h}
1117 printf '# ifdef HAVE_EDITLINE\n ",EDITLINE"\n# endif\n' >> ${h}
1118 printf '# ifdef HAVE_NCL\n ",NCL"\n# endif\n' >> ${h}
1119 printf '# ifdef HAVE_TABEXPAND\n ",TABEXPAND"\n# endif\n' >> ${h}
1120 printf '# ifdef HAVE_HISTORY\n ",HISTORY MANAGEMENT"\n# endif\n' >> ${h}
1121 printf '# ifdef HAVE_QUOTE_FOLD\n ",QUOTE-FOLD"\n# endif\n' >> ${h}
1122 printf '# ifdef HAVE_COLOUR\n ",COLOUR"\n# endif\n' >> ${h}
1123 printf '# ifdef HAVE_DEBUG\n ",DEBUG"\n# endif\n' >> ${h}
1124 printf ';\n#endif /* _MAIN_SOURCE */\n' >> ${h}
1126 printf '#endif /* _CONFIG_H */\n' >> ${h}
1127 ${rm} -f ${tmp}
1129 # Create the real mk.mk
1130 ${rm} -rf ${tmp0}.* ${tmp0}*
1131 printf 'OBJ_SRC = ' >> ${mk}
1132 if nwantfeat AMALGAMATION; then
1133 echo *.c >> ${mk}
1134 echo 'OBJ_DEP =' >> ${mk}
1135 else
1136 j=`echo "${src}" | sed 's/^.\///'`
1137 echo "${j}" >> ${mk}
1138 printf 'OBJ_DEP = main.c ' >> ${mk}
1139 printf '#define _MAIN_SOURCE\n' >> ${src}
1140 printf '#include "nail.h"\n#include "main.c"\n' >> ${src}
1141 for i in *.c; do
1142 if [ "${i}" = "${j}" ] || [ "${i}" = main.c ]; then
1143 continue
1145 printf "${i} " >> ${mk}
1146 printf "#include \"${i}\"\n" >> ${src}
1147 done
1148 echo >> ${mk}
1151 echo "LIBS = `${cat} ${lib}`" >> ${mk}
1152 echo "INCLUDES = `${cat} ${inc}`" >> ${mk}
1153 echo >> ${mk}
1154 ${cat} ./mk-mk.in >> ${mk}
1156 ## Finished! ##
1158 ${cat} > ${tmp2}.c << \!
1159 #include "config.h"
1160 #ifdef HAVE_NL_LANGINFO
1161 # include <langinfo.h>
1162 #endif
1164 :The following optional features are enabled:
1165 #ifdef HAVE_ICONV
1166 : + Character set conversion using iconv()
1167 #endif
1168 #ifdef HAVE_SETLOCALE
1169 : + Locale support: Printable characters depend on the environment
1170 # ifdef HAVE_C90AMEND1
1171 : + Multibyte character support
1172 # endif
1173 # ifdef HAVE_NL_LANGINFO
1174 : + Automatic detection of terminal character set
1175 # endif
1176 #endif
1177 #ifdef HAVE_SOCKETS
1178 : + Network support
1179 #endif
1180 #ifdef HAVE_IPV6
1181 : + Support for Internet Protocol v6 (IPv6)
1182 #endif
1183 #ifdef HAVE_SSL
1184 # ifdef HAVE_OPENSSL
1185 : + S/MIME and SSL/TLS using OpenSSL
1186 # endif
1187 #endif
1188 #ifdef HAVE_IMAP
1189 : + IMAP protocol
1190 #endif
1191 #ifdef HAVE_GSSAPI
1192 : + IMAP GSSAPI authentication
1193 #endif
1194 #ifdef HAVE_POP3
1195 : + POP3 protocol
1196 #endif
1197 #ifdef HAVE_SMTP
1198 : + SMTP protocol
1199 #endif
1200 #ifdef HAVE_SPAM
1201 : + Interaction with spam filters
1202 #endif
1203 #ifdef HAVE_IDNA
1204 : + IDNA (internationalized domain names for applications) support
1205 #endif
1206 #ifdef HAVE_REGEX
1207 : + Regular expression searches
1208 #endif
1209 #if defined HAVE_READLINE || defined HAVE_EDITLINE || defined HAVE_NCL
1210 : + Command line editing
1211 # ifdef HAVE_TABEXPAND
1212 : + + Tabulator expansion
1213 # endif
1214 # ifdef HAVE_HISTORY
1215 : + + History management
1216 # endif
1217 #endif
1218 #ifdef HAVE_QUOTE_FOLD
1219 : + Extended *quote-fold*ing
1220 #endif
1221 #ifdef HAVE_COLOUR
1222 : + Coloured message display (simple)
1223 #endif
1225 :The following optional features are disabled:
1226 #ifndef HAVE_ICONV
1227 : - Character set conversion using iconv()
1228 #endif
1229 #ifndef HAVE_SETLOCALE
1230 : - Locale support: Only ASCII characters are recognized
1231 #endif
1232 # ifndef HAVE_C90AMEND1
1233 : - Multibyte character support
1234 # endif
1235 # ifndef HAVE_NL_LANGINFO
1236 : - Automatic detection of terminal character set
1237 # endif
1238 #ifndef HAVE_SOCKETS
1239 : - Network support
1240 #endif
1241 #ifndef HAVE_IPV6
1242 : - Support for Internet Protocol v6 (IPv6)
1243 #endif
1244 #if !defined HAVE_SSL
1245 : - SSL/TLS (network transport authentication and encryption)
1246 #endif
1247 #ifndef HAVE_IMAP
1248 : - IMAP protocol
1249 #endif
1250 #ifndef HAVE_GSSAPI
1251 : - IMAP GSSAPI authentication
1252 #endif
1253 #ifndef HAVE_POP3
1254 : - POP3 protocol
1255 #endif
1256 #ifndef HAVE_SMTP
1257 : - SMTP protocol
1258 #endif
1259 #ifndef HAVE_SPAM
1260 : - Interaction with spam filters
1261 #endif
1262 #ifndef HAVE_IDNA
1263 : - IDNA (internationalized domain names for applications) support
1264 #endif
1265 #ifndef HAVE_REGEX
1266 : - Regular expression searches
1267 #endif
1268 #if !defined HAVE_READLINE && !defined HAVE_EDITLINE && !defined HAVE_NCL
1269 : - Command line editing and history
1270 #endif
1271 #ifndef HAVE_QUOTE_FOLD
1272 : - Extended *quote-fold*ing
1273 #endif
1274 #ifndef HAVE_COLOUR
1275 : - Coloured message display (simple)
1276 #endif
1278 :Remarks:
1279 #ifndef HAVE_SNPRINTF
1280 : . The function snprintf() could not be found. mailx will be compiled to use
1281 : sprintf() instead. This might overflow buffers if input values are larger
1282 : than expected. Use the resulting binary with care or update your system
1283 : environment and start the configuration process again.
1284 #endif
1285 #ifndef HAVE_FCHDIR
1286 : . The function fchdir() could not be found. mailx will be compiled to use
1287 : chdir() instead. This is not a problem unless the current working
1288 : directory of mailx is moved while the IMAP cache is used.
1289 #endif
1290 #ifndef HAVE_GETOPT
1291 : . Using a minimal builtin POSIX-like getopt()
1292 #endif
1293 #ifdef HAVE_DEBUG
1294 : . Debug enabled binary: not meant to be used by end-users: THANKS!
1295 #endif
1299 ${make} -f ${makefile} ${tmp2}.x
1300 < ${tmp2}.x >&5 ${sed} -e '/^[^:]/d; /^$/d; s/^://'
1302 # vim:set fenc=utf-8:s-it-mode