Do not use non-compiler-builtin alloca(3)s..
[s-mailx.git] / makeconfig
blob5f6af50e36b0232d34f8c202f8484b5109d90372
1 #!/bin/sh
3 [ -z "${WANT_ASSERTS}" ] && WANT_ASSERTS=0
4 if [ -z "${CONFIG}" ]; then
5 [ -f user.conf ] && . user.conf
6 else
7 case ${CONFIG} in
8 MINIMAL)
9 WANT_JUNK=0 WANT_SOCKET=0
11 NETLESS)
12 WANT_SOCKET=0
14 NETSEND)
15 WANT_JUNK=0 WANT_IMAP=0 WANT_POP3=0
18 echo >&2 "Unknown CONFIG= setting: ${CONFIG}"
19 echo >&2 'Possible values: MINIMAL, NETLESS, NETSEND'
20 exit 1
21 esac
24 wantfeat() {
25 eval i=\$WANT_${1}
26 [ "${i}" != "0" ]
28 nwantfeat() {
29 eval i=\$WANT_${1}
30 [ "${i}" = "0" ]
33 if nwantfeat SOCKET; then
34 WANT_IPV6=0 WANT_SSL=0
35 WANT_IMAP=0 WANT_GSSAPI=0 WANT_POP3=0 WANT_SMTP=0
37 if nwantfeat IMAP && nwantfeat POP3 && nwantfeat SMTP; then
38 WANT_SOCKET=0 WANT_IPV6=0 WANT_SSL=0
39 else
40 WANT_SOCKET=1
42 if nwantfeat IMAP; then
43 WANT_GSSAPI=0
45 # If we don't need MD5 except for producing boundary and message-id strings,
46 # leave it off, plain old srand(3) should be enough for that purpose.
47 if nwantfeat SOCKET && nwantfeat JUNK; then
48 WANT_MD5=0
49 elif wantfeat JUNK; then
50 WANT_MD5=1
53 tmp=___build$$
54 tmp2=___tmp1$$
55 tmp3=___tmp2$$
56 out=config.h
57 log=config.log
58 lib=LIBS
59 inc=INCS
60 makefile=config.mk
62 make="${MAKE-make}"
64 exec 5>&2 >$log 2>&1
66 rm -f $out $lib $inc
67 echo "\
69 * Auto-generated by $0.
70 * Changes are lost when $0 is run again.
72 " > $out
73 : > $lib
74 : > $inc
75 cat > $makefile << \!
76 .SUFFIXES: .o .c .x .y
77 .c.o:
78 $(CC) $(CFLAGS) $(INCLUDES) -c $<
80 .c.x:
81 $(CC) $(CFLAGS) $(INCLUDES) -E $< >$@
83 .c:
84 $(CC) $(CFLAGS) $(INCLUDES) $(LDFLAGS) $< $(LIBS) -o $@
86 .y: ;
90 trap "rm -f $out $lib $inc $makefile; exit" 1 2 15
91 trap "rm -rf $tmp.*; rm -f $tmp $tmp2.? $tmp2 $tmp3.? $tmp3 $makefile" 0
93 msg() {
94 fmt=$1
95 shift
96 printf "*** $fmt\\n" "$@"
97 printf "$fmt" "$@" >&5
100 compile_check() {
101 variable=$1
102 topic=$2
103 define=$3
105 echo '************************************************************'
106 msg "checking $topic ... "
107 echo "/* checked $topic */" >>$out
108 rm -f $tmp.o
109 echo '*** test program is'
110 tee $tmp.c
111 #echo '*** the preprocessor generates'
112 #$make -f $makefile $tmp.x
113 #cat $tmp.x
114 echo '*** results are'
115 if $make -f $makefile $tmp.o && test -f $tmp.o
116 then
117 msg "okay\\n"
118 echo "$define" >>$out
119 eval have_$variable=yes
120 return 0
121 else
122 echo "/* $define */" >>$out
123 msg "no\\n"
124 eval unset have_$variable
125 return 1
129 link_check() {
130 variable=$1
131 topic=$2
132 define=$3
133 libs=$4
134 incs=$5
136 echo '************************************************************'
137 msg "checking $topic ... "
138 echo "/* checked $topic */" >>$out
139 rm -f $tmp $tmp.o
140 echo '*** test program is'
141 tee $tmp.c
142 #echo '*** the preprocessor generates'
143 #$make -f $makefile $tmp.x
144 #cat $tmp.x
145 echo '*** results are'
146 if $make -f $makefile \
147 $tmp INCLUDES="$INCLUDES $incs" LIBS="$LIBS $libs" &&
148 test -f $tmp
149 then
150 msg "okay\\n"
151 echo "$define" >> $out
152 echo "$libs" >> $lib
153 echo "$incs" >> $inc
154 eval have_$variable=yes
155 return 0
156 else
157 msg "no\\n"
158 echo "/* $define */" >>$out
159 eval unset have_$variable
160 return 1
164 link_check hello 'if a hello world program can be built' <<\! || { \
165 echo 'This problem is most certainly not specific to this software.' >&5; \
166 echo "Read the file '$log' and check your compiler installation." >&5; \
167 rm $out; exit 1; \
169 #include <stdio.h>
171 int main(int argc, char *argv[])
173 (void)argc;
174 (void)argv;
175 puts("hello world");
176 return 0;
180 # Due to NetBSD PR lib/47120 it seems to be best to not use non-cc-builtin
181 # versions of alloca(3) since modern compilers just can't be trusted not to
182 # overoptimize and silently break some code
183 link_check alloca 'for __builtin_alloca()' \
184 '#define HAVE_ALLOCA __builtin_alloca' << \!
185 int main(void)
187 __builtin_alloca(1);
188 return 0;
192 compile_check ssize_t 'for ssize_t' '#define HAVE_SSIZE_T' <<\!
193 #include <sys/types.h>
194 #include <unistd.h>
195 int main(void)
197 ssize_t i = 3;
198 write(1, "foo", i);
199 return 0;
203 link_check snprintf 'for snprintf()' '#define HAVE_SNPRINTF' <<\!
204 #include <stdio.h>
205 int main(void)
207 char b[20];
208 snprintf(b, sizeof b, "%s", "string");
209 return 0;
213 link_check putc_unlocked 'for putc_unlocked()' '#define HAVE_PUTC_UNLOCKED' <<\!
214 #include <stdio.h>
215 int main(void)
217 putc_unlocked('@', stdout);
218 return 0;
222 link_check fchdir 'for fchdir()' '#define HAVE_FCHDIR' <<\!
223 #include <unistd.h>
224 int main(void)
226 fchdir(0);
227 return 0;
231 link_check mmap 'for mmap()' '#define HAVE_MMAP' <<\!
232 #include <sys/types.h>
233 #include <sys/mman.h>
234 int main(void)
236 mmap(0, 0, 0, 0, 0, 0);
237 return 0;
241 link_check mremap 'for mremap()' '#define HAVE_MREMAP' <<\!
242 #include <sys/types.h>
243 #include <sys/mman.h>
244 int main(void)
246 mremap(0, 0, 0, MREMAP_MAYMOVE);
247 return 0;
251 cat >$tmp2.c <<\!
252 #include <iconv.h>
253 int main(void)
255 iconv_t id;
257 id = iconv_open("foo", "bar");
258 return 0;
261 <$tmp2.c link_check iconv 'for iconv functionality' '#define HAVE_ICONV' ||
262 <$tmp2.c link_check iconv 'for iconv functionality in libiconv' \
263 '#define HAVE_ICONV' '-liconv'
265 link_check wctype 'for wctype functionality' '#define HAVE_WCTYPE_H' <<\!
266 #include <wctype.h>
267 int main(void)
269 iswprint(L'c');
270 towupper(L'c');
271 return 0;
275 link_check wcwidth 'for wcwidth() ' '#define HAVE_WCWIDTH' <<\!
276 #include <wchar.h>
277 int main(void)
279 wcwidth(L'c');
280 return 0;
284 link_check mbtowc 'for mbtowc()' '#define HAVE_MBTOWC' <<\!
285 #include <stdlib.h>
286 int main(void)
288 wchar_t wc;
289 mbtowc(&wc, "x", 1);
290 return 0;
294 link_check setlocale 'for setlocale()' '#define HAVE_SETLOCALE' <<\!
295 #include <locale.h>
296 int main(void)
298 setlocale(LC_ALL, "");
299 return 0;
303 link_check nl_langinfo 'for nl_langinfo()' '#define HAVE_NL_LANGINFO' <<\!
304 #include <langinfo.h>
305 int main(void)
307 nl_langinfo(DAY_1);
308 return 0;
312 link_check mkstemp 'for mkstemp()' '#define HAVE_MKSTEMP' <<\!
313 #include <stdlib.h>
314 int main(void)
316 mkstemp("x");
317 return 0;
321 link_check fpathconf 'for fpathconf()' '#define HAVE_FPATHCONF' <<\!
322 #include <unistd.h>
323 int main(void)
325 fpathconf(0, _PC_PATH_MAX);
326 return 0;
330 link_check wordexp 'for wordexp()' '#define HAVE_WORDEXP' <<\!
331 #include <wordexp.h>
332 int main(void)
334 wordexp((char *)0, (wordexp_t *)0, 0);
335 return 0;
339 link_check getopt 'for getopt()' '#define HAVE_GETOPT' << \!
340 #include <unistd.h>
341 int main(int argc, char **argv)
343 #if defined __GLIBC__ || defined __linux__
344 Argument and option reordering is not a desired feature.
345 #else
346 getopt(argc, argv, "oPt");
347 #endif
348 return (((long)optarg + optind) & 0x7F);
354 if wantfeat SOCKET; then
355 compile_check arpa_inet_h 'for <arpa/inet.h>' \
356 '#define HAVE_ARPA_INET_H' << \!
357 #include "config.h"
358 #include <sys/types.h>
359 #include <sys/socket.h>
360 #include <netdb.h>
361 #include <netinet/in.h>
362 #include <arpa/inet.h>
365 cat >$tmp2.c << \!
366 #include "config.h"
367 #include <sys/types.h>
368 #include <sys/socket.h>
369 #include <netdb.h>
370 #include <netinet/in.h>
371 #ifdef HAVE_ARPA_INET_H
372 #include <arpa/inet.h>
373 #endif
375 int main(void)
377 struct sockaddr s;
378 socket(AF_INET, SOCK_STREAM, 0);
379 connect(0, &s, 0);
380 gethostbyname("foo");
381 return 0;
385 WANT_SOCKET=1
386 <$tmp2.c link_check sockets 'for sockets in libc' \
387 '#define HAVE_SOCKETS' ||
388 <$tmp2.c link_check sockets 'for sockets in libnsl' \
389 '#define HAVE_SOCKETS' '-lnsl' ||
390 <$tmp2.c link_check sockets \
391 'for sockets in libsocket and libnsl' \
392 '#define HAVE_SOCKETS' '-lsocket -lnsl' ||
393 WANT_SOCKET=0
395 # XXX Shouldn't it be a hard error if there is no socket support, then?
396 [ ${WANT_SOCKET} -eq 1 ] ||
397 WANT_IPV6=0 WANT_SSL=0 \
398 WANT_IMAP=0 WANT_GSSAPI=0 WANT_POP3=0 WANT_SMTP=0
399 fi # wantfeat SOCKET
401 if wantfeat IPV6; then
402 link_check ipv6 'for IPv6 functionality' '#define USE_IPV6' << \!
403 #include "config.h"
404 #include <sys/types.h>
405 #include <sys/socket.h>
406 #include <netdb.h>
407 #include <netinet/in.h>
408 #ifdef HAVE_ARPA_INET_H
409 #include <arpa/inet.h>
410 #endif
412 int main(void)
414 struct addrinfo a, *ap;
415 getaddrinfo("foo", "0", &a, &ap);
416 return 0;
420 fi # wantfeat IPV6
422 if wantfeat IMAP; then
423 echo "#define USE_IMAP" >> $out
424 else
425 echo "/* #define USE_IMAP */" >> $out
428 if wantfeat POP3; then
429 echo "#define USE_POP3" >>$out
430 else
431 echo "/* #define USE_POP3 */" >> $out
434 if wantfeat SMTP; then
435 echo "#define USE_SMTP" >>$out
436 else
437 echo "/* #define USE_SMTP */" >> $out
440 if wantfeat SSL; then
441 link_check nss 'for Network Security Services (NSS)' '#define USE_SSL
442 #define USE_NSS' \
443 '-lsmime3 -lnss3 -lssl3 -lnspr4 -lplc4' <<\! || \
444 link_check openssl 'for sufficiently recent OpenSSL' \
445 '#define USE_SSL
446 #define USE_OPENSSL' '-lssl -lcrypto' << \%
447 #include <nss.h>
448 #include <ssl.h>
449 #include <prinit.h>
450 #include <prmem.h>
451 #include <pk11func.h>
452 #include <prtypes.h>
453 #include <prerror.h>
454 #include <secerr.h>
455 #include <smime.h>
456 #include <ciferfam.h>
457 #include <private/pprio.h>
459 int main(void)
461 PR_ImportTCPSocket(0);
462 NSS_CMSSignerInfo_AddSMIMECaps(0);
463 return 0;
466 #include <openssl/ssl.h>
467 #include <openssl/err.h>
468 #include <openssl/x509v3.h>
469 #include <openssl/x509.h>
470 #include <openssl/rand.h>
472 int main(void)
474 SSLv23_client_method();
475 PEM_read_PrivateKey(0, 0, 0, 0);
476 return 0;
480 if [ "${have_nss}" = 'yes' ]; then
481 compile_check genname_h 'for genname.h' \
482 '#define HAVE_GENNAME_H' << \!
483 #include <genname.h>
486 compile_check xconst_h 'for xconst.h' \
487 '#define HAVE_XCONST_H' << \!
488 #include <xconst.h>
491 compile_check CERTAltNameEncodedContext \
492 'for CERTAltNameEncodedContext type' \
493 '#define HAVE_CERTAltNameEncodedContext' << \!
494 #include "config.h"
495 #include <nss.h>
496 #include <ssl.h>
497 #include <prinit.h>
498 #include <prmem.h>
499 #include <pk11func.h>
500 #include <prtypes.h>
501 #include <prerror.h>
502 #include <secerr.h>
503 #include <smime.h>
504 #include <ciferfam.h>
505 #ifdef HAVE_XCONST_H
506 #include <xconst.h>
507 #endif
508 #ifdef HAVE_GENNAME_H
509 #include <genname.h>
510 #endif
511 #include <private/pprio.h>
513 CERTAltNameEncodedContext foo;
517 if [ "${have_openssl}" = 'yes' ]; then
518 compile_check stack_of 'for STACK_OF()' \
519 '#define HAVE_STACK_OF' << \!
520 #include <openssl/ssl.h>
521 #include <openssl/err.h>
522 #include <openssl/x509v3.h>
523 #include <openssl/x509.h>
524 #include <openssl/rand.h>
526 int main(void)
528 STACK_OF(GENERAL_NAME) *gens = NULL;
529 printf("%p", gens); /* to make it used */
530 SSLv23_client_method();
531 PEM_read_PrivateKey(0, 0, 0, 0);
532 return 0;
537 else
538 echo '/* Socket/SSL support not desired */' >> $out
539 fi # wantfeat SSL
541 if wantfeat GSSAPI; then
542 cat >$tmp2.c <<\!
543 #include <gssapi/gssapi.h>
545 int main(void)
547 gss_import_name(0, 0, GSS_C_NT_HOSTBASED_SERVICE, 0);
548 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
549 return 0;
553 sed -e '1s/gssapi\///' < $tmp2.c > $tmp3.c
555 <$tmp2.c link_check gssapi 'for GSSAPI in libgss' \
556 '#define USE_GSSAPI' '-lgss' ||
557 <$tmp2.c link_check gssapi 'for GSSAPI in libgssapi_krb5' \
558 '#define USE_GSSAPI' '-lgssapi_krb5' ||
559 link_check gssapi 'for GSSAPI in libgssapi_krb5, old-style' \
560 '#define USE_GSSAPI
561 #define GSSAPI_OLD_STYLE' '-lgssapi_krb5' <<\! || \
562 <$tmp3.c link_check gssapi 'for GSSAPI in libgssapi' \
563 '#define USE_GSSAPI
564 #define GSSAPI_REG_INCLUDE' '-lgssapi' || \
565 <$tmp3.c link_check gssapi \
566 'for GSSAPI in libgssapi, OpenBSD-style' \
567 '#define USE_GSSAPI
568 #define GSSAPI_REG_INCLUDE' \
569 '-lgssapi -lkrb5 -lcrypto' '-I/usr/include/kerberosV'
571 #include <gssapi/gssapi.h>
572 #include <gssapi/gssapi_generic.h>
574 int main(void)
576 gss_import_name(0, 0, gss_nt_service_name, 0);
577 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
578 return 0;
582 else
583 echo '/* IMAP/GSSAPI support not desired */' >> $out
584 fi # wantfeat GSSAPI
586 if wantfeat IDNA; then
587 link_check idna 'for GNU Libidn' '#define USE_IDNA' '-lidn' << \!
588 #include <idna.h>
589 #include <stringprep.h>
590 #include <tld.h>
592 int main(void)
594 char *utf8, *idna_ascii;
595 uint32_t *idna_uni;
596 size_t sz;
597 utf8 = stringprep_locale_to_utf8("does.this.work");
598 if (idna_to_ascii_8z(utf8, &idna_ascii, IDNA_USE_STD3_ASCII_RULES)
599 != IDNA_SUCCESS)
600 return (1);
601 if (idna_to_unicode_8z4z(idna_ascii, &idna_uni, 0) != IDNA_SUCCESS)
602 return (1 + (unsigned char)idna_strerror(0)[0]);
603 if (tld_check_4z(idna_uni, &sz, NULL) != TLD_SUCCESS)
604 return (2 + (unsigned char)tld_strerror(0)[0]);
605 return (0);
609 else
610 echo '/* IDNA support not desired */' >> $out
611 fi # wantfeat IDNA
613 if wantfeat JUNK; then
614 echo "#define USE_JUNK" >> $out
615 else
616 echo "/* #define USE_JUNK */" >> $out
619 if wantfeat MD5; then
620 echo "#define USE_MD5" >> $out
621 else
622 echo "/* #define USE_MD5 */" >> $out
625 if wantfeat ASSERTS; then
626 echo "#define HAVE_ASSERTS" >> $out
627 else
628 echo "/* #define HAVE_ASSERTS */" >> $out
631 # Since we cat(1) the content of those to cc/"ld", convert them to single line
632 squeeze_em() {
633 < "${1}" > "${2}" awk \
634 'BEGIN {ORS = " "} /^[^#]/ {print} {next} END {ORS = ""; print "\n"}'
636 rm -f "$tmp"
637 squeeze_em "$inc" "$tmp"
638 mv "$tmp" "$inc"
639 squeeze_em "$lib" "$tmp"
640 mv "$tmp" "$lib"
642 # Finished!
643 cat > $tmp2.c << \!
644 #include "config.h"
645 #ifdef HAVE_NL_LANGINFO
646 #include <langinfo.h>
647 #endif
649 :The following optional features are enabled:
650 #ifdef HAVE_SETLOCALE
651 : + Locale support: Printable characters depend on the environment
652 #if defined HAVE_MBTOWC && defined HAVE_WCTYPE_H
653 : + Multibyte character support
654 #endif
655 #endif
656 #ifdef HAVE_ICONV
657 : + Character set conversion using iconv()
658 #endif
659 #if defined HAVE_SETLOCALE && defined HAVE_NL_LANGINFO && defined CODESET
660 : + Automatic detection of terminal character set
661 #endif
662 #ifdef HAVE_SOCKETS
663 : + Network support
664 #endif
665 #ifdef USE_IPV6
666 : + Support for Internet Protocol v6 (IPv6)
667 #endif
668 #ifdef USE_NSS
669 : + S/MIME and SSL/TLS using Network Security Services (NSS)
670 #endif
671 #ifdef USE_OPENSSL
672 : + S/MIME and SSL/TLS using OpenSSL
673 #endif
674 #ifdef USE_IMAP
675 : + IMAP protocol
676 #endif
677 #ifdef USE_GSSAPI
678 : + IMAP GSSAPI authentication
679 #endif
680 #ifdef USE_POP3
681 : + POP3 protocol
682 #endif
683 #ifdef USE_SMTP
684 : + SMTP protocol
685 #endif
686 #ifdef USE_JUNK
687 : + Junk-mail management (Bayesian filtering)
688 #endif
689 #ifdef USE_MD5
690 : + The MD5 message digest
691 #endif
692 #ifdef USE_IDNA
693 : + IDNA (internationalized domain names for applications) support
694 #endif
696 :The following optional features are disabled:
697 #ifndef HAVE_SETLOCALE
698 : - Locale support: Only ASCII characters are recognized
699 #endif
700 #if ! defined HAVE_SETLOCALE || ! defined HAVE_MBTOWC || !defined HAVE_WCTYPE_H
701 : - Multibyte character support
702 #endif
703 #ifndef HAVE_ICONV
704 : - Character set conversion using iconv()
705 #endif
706 #if ! defined HAVE_SETLOCALE || ! defined HAVE_NL_LANGINFO || ! defined CODESET
707 : - Automatic detection of terminal character set
708 #endif
709 #ifndef HAVE_SOCKETS
710 : - Network support
711 #endif
712 #ifndef USE_IPV6
713 : - Support for Internet Protocol v6 (IPv6)
714 #endif
715 #if ! defined USE_SSL && ! defined USE_NSS
716 : - SSL/TLS (network transport authentication and encryption)
717 #endif
718 #ifndef USE_IMAP
719 : - IMAP protocol
720 #endif
721 #ifndef USE_GSSAPI
722 : - IMAP GSSAPI authentication
723 #endif
724 #ifndef USE_POP3
725 : - POP3 protocol
726 #endif
727 #ifndef USE_SMTP
728 : - SMTP protocol
729 #endif
730 #ifndef USE_JUNK
731 : - Junk-mail management (Bayesian filtering)
732 #endif
733 #ifndef USE_MD5
734 : - The MD5 message digest
735 #endif
736 #ifndef USE_IDNA
737 : - IDNA (internationalized domain names for applications) support
738 #endif
740 :Remarks:
741 #ifndef HAVE_SNPRINTF
742 : * The function snprintf() could not be found. mailx will be compiled to use
743 : sprintf() instead. This might overflow buffers if input values are larger
744 : than expected. Use the resulting binary with care or update your system
745 : environment and start the configuration process again.
746 #endif
747 #ifndef HAVE_FCHDIR
748 : * The function fchdir() could not be found. mailx will be compiled to use
749 : chdir() instead. This is not a problem unless the current working
750 : directory of mailx is moved while the IMAP cache is used.
751 #endif
752 #ifndef HAVE_GETOPT
753 : * A (usable) getopt() functionality could not be found.
754 : A builtin version is used instead.
755 #endif
756 #ifdef HAVE_ASSERTS
757 : * WANT_ASSERTS is enabled, the program binary will contain code assertions.
758 : There are also additional commands available, like "core".
759 : Such a binary is not meant to be used by end-users, but only for
760 : development purposes. Thanks!
761 #endif
765 $make -f $makefile $tmp2.x
766 < $tmp2.x >&5 sed '/^[^:]/d; /^$/d; s/^://'
768 exit 0