*m*ail and *M*ail support all recipients! Use lextract()
[s-mailx.git] / makeconfig
blob2d8df385514420dbe2a6d65192f9bcb2b9f1c401
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 compile_check alloca_h 'for <alloca.h>' '#define HAVE_ALLOCA_H' <<\!
181 #include <alloca.h>
184 link_check alloca 'for alloca()' '#define HAVE_ALLOCA' <<\!
185 #include "rcv.h"
186 int main(void)
188 alloca(1);
189 return 0;
193 compile_check ssize_t 'for ssize_t' '#define HAVE_SSIZE_T' <<\!
194 #include <sys/types.h>
195 #include <unistd.h>
196 int main(void)
198 ssize_t i = 3;
199 write(1, "foo", i);
200 return 0;
204 link_check snprintf 'for snprintf()' '#define HAVE_SNPRINTF' <<\!
205 #include <stdio.h>
206 int main(void)
208 char b[20];
209 snprintf(b, sizeof b, "%s", "string");
210 return 0;
214 link_check putc_unlocked 'for putc_unlocked()' '#define HAVE_PUTC_UNLOCKED' <<\!
215 #include <stdio.h>
216 int main(void)
218 putc_unlocked('@', stdout);
219 return 0;
223 link_check fchdir 'for fchdir()' '#define HAVE_FCHDIR' <<\!
224 #include <unistd.h>
225 int main(void)
227 fchdir(0);
228 return 0;
232 link_check mmap 'for mmap()' '#define HAVE_MMAP' <<\!
233 #include <sys/types.h>
234 #include <sys/mman.h>
235 int main(void)
237 mmap(0, 0, 0, 0, 0, 0);
238 return 0;
242 link_check mremap 'for mremap()' '#define HAVE_MREMAP' <<\!
243 #include <sys/types.h>
244 #include <sys/mman.h>
245 int main(void)
247 mremap(0, 0, 0, MREMAP_MAYMOVE);
248 return 0;
252 cat >$tmp2.c <<\!
253 #include <iconv.h>
254 int main(void)
256 iconv_t id;
258 id = iconv_open("foo", "bar");
259 return 0;
262 <$tmp2.c link_check iconv 'for iconv functionality' '#define HAVE_ICONV' ||
263 <$tmp2.c link_check iconv 'for iconv functionality in libiconv' \
264 '#define HAVE_ICONV' '-liconv'
266 link_check wctype 'for wctype functionality' '#define HAVE_WCTYPE_H' <<\!
267 #include <wctype.h>
268 int main(void)
270 iswprint(L'c');
271 towupper(L'c');
272 return 0;
276 link_check wcwidth 'for wcwidth() ' '#define HAVE_WCWIDTH' <<\!
277 #include <wchar.h>
278 int main(void)
280 wcwidth(L'c');
281 return 0;
285 link_check mbtowc 'for mbtowc()' '#define HAVE_MBTOWC' <<\!
286 #include <stdlib.h>
287 int main(void)
289 wchar_t wc;
290 mbtowc(&wc, "x", 1);
291 return 0;
295 link_check setlocale 'for setlocale()' '#define HAVE_SETLOCALE' <<\!
296 #include <locale.h>
297 int main(void)
299 setlocale(LC_ALL, "");
300 return 0;
304 link_check nl_langinfo 'for nl_langinfo()' '#define HAVE_NL_LANGINFO' <<\!
305 #include <langinfo.h>
306 int main(void)
308 nl_langinfo(DAY_1);
309 return 0;
313 link_check mkstemp 'for mkstemp()' '#define HAVE_MKSTEMP' <<\!
314 #include <stdlib.h>
315 int main(void)
317 mkstemp("x");
318 return 0;
322 link_check fpathconf 'for fpathconf()' '#define HAVE_FPATHCONF' <<\!
323 #include <unistd.h>
324 int main(void)
326 fpathconf(0, _PC_PATH_MAX);
327 return 0;
331 link_check wordexp 'for wordexp()' '#define HAVE_WORDEXP' <<\!
332 #include <wordexp.h>
333 int main(void)
335 wordexp((char *)0, (wordexp_t *)0, 0);
336 return 0;
340 link_check getopt 'for getopt()' '#define HAVE_GETOPT' << \!
341 #include <unistd.h>
342 int main(int argc, char **argv)
344 #if defined __GLIBC__ || defined __linux__
345 Argument and option reordering is not a desired feature.
346 #else
347 getopt(argc, argv, "oPt");
348 #endif
349 return (((long)optarg + optind) & 0x7F);
355 if wantfeat SOCKET; then
356 compile_check arpa_inet_h 'for <arpa/inet.h>' \
357 '#define HAVE_ARPA_INET_H' << \!
358 #include "config.h"
359 #include <sys/types.h>
360 #include <sys/socket.h>
361 #include <netdb.h>
362 #include <netinet/in.h>
363 #include <arpa/inet.h>
366 cat >$tmp2.c << \!
367 #include "config.h"
368 #include <sys/types.h>
369 #include <sys/socket.h>
370 #include <netdb.h>
371 #include <netinet/in.h>
372 #ifdef HAVE_ARPA_INET_H
373 #include <arpa/inet.h>
374 #endif
376 int main(void)
378 struct sockaddr s;
379 socket(AF_INET, SOCK_STREAM, 0);
380 connect(0, &s, 0);
381 gethostbyname("foo");
382 return 0;
386 WANT_SOCKET=1
387 <$tmp2.c link_check sockets 'for sockets in libc' \
388 '#define HAVE_SOCKETS' ||
389 <$tmp2.c link_check sockets 'for sockets in libnsl' \
390 '#define HAVE_SOCKETS' '-lnsl' ||
391 <$tmp2.c link_check sockets \
392 'for sockets in libsocket and libnsl' \
393 '#define HAVE_SOCKETS' '-lsocket -lnsl' ||
394 WANT_SOCKET=0
396 # XXX Shouldn't it be a hard error if there is no socket support, then?
397 [ ${WANT_SOCKET} -eq 1 ] ||
398 WANT_IPV6=0 WANT_SSL=0 \
399 WANT_IMAP=0 WANT_GSSAPI=0 WANT_POP3=0 WANT_SMTP=0
400 fi # wantfeat SOCKET
402 if wantfeat IPV6; then
403 link_check ipv6 'for IPv6 functionality' '#define USE_IPV6' << \!
404 #include "config.h"
405 #include <sys/types.h>
406 #include <sys/socket.h>
407 #include <netdb.h>
408 #include <netinet/in.h>
409 #ifdef HAVE_ARPA_INET_H
410 #include <arpa/inet.h>
411 #endif
413 int main(void)
415 struct addrinfo a, *ap;
416 getaddrinfo("foo", "0", &a, &ap);
417 return 0;
421 fi # wantfeat IPV6
423 if wantfeat IMAP; then
424 echo "#define USE_IMAP" >> $out
425 else
426 echo "/* #define USE_IMAP */" >> $out
429 if wantfeat POP3; then
430 echo "#define USE_POP3" >>$out
431 else
432 echo "/* #define USE_POP3 */" >> $out
435 if wantfeat SMTP; then
436 echo "#define USE_SMTP" >>$out
437 else
438 echo "/* #define USE_SMTP */" >> $out
441 if wantfeat SSL; then
442 link_check nss 'for Network Security Services (NSS)' '#define USE_SSL
443 #define USE_NSS' \
444 '-lsmime3 -lnss3 -lssl3 -lnspr4 -lplc4' <<\! || \
445 link_check openssl 'for sufficiently recent OpenSSL' \
446 '#define USE_SSL
447 #define USE_OPENSSL' '-lssl -lcrypto' << \%
448 #include <nss.h>
449 #include <ssl.h>
450 #include <prinit.h>
451 #include <prmem.h>
452 #include <pk11func.h>
453 #include <prtypes.h>
454 #include <prerror.h>
455 #include <secerr.h>
456 #include <smime.h>
457 #include <ciferfam.h>
458 #include <private/pprio.h>
460 int main(void)
462 PR_ImportTCPSocket(0);
463 NSS_CMSSignerInfo_AddSMIMECaps(0);
464 return 0;
467 #include <openssl/ssl.h>
468 #include <openssl/err.h>
469 #include <openssl/x509v3.h>
470 #include <openssl/x509.h>
471 #include <openssl/rand.h>
473 int main(void)
475 SSLv23_client_method();
476 PEM_read_PrivateKey(0, 0, 0, 0);
477 return 0;
481 if [ "${have_nss}" = 'yes' ]; then
482 compile_check genname_h 'for genname.h' \
483 '#define HAVE_GENNAME_H' << \!
484 #include <genname.h>
487 compile_check xconst_h 'for xconst.h' \
488 '#define HAVE_XCONST_H' << \!
489 #include <xconst.h>
492 compile_check CERTAltNameEncodedContext \
493 'for CERTAltNameEncodedContext type' \
494 '#define HAVE_CERTAltNameEncodedContext' << \!
495 #include "config.h"
496 #include <nss.h>
497 #include <ssl.h>
498 #include <prinit.h>
499 #include <prmem.h>
500 #include <pk11func.h>
501 #include <prtypes.h>
502 #include <prerror.h>
503 #include <secerr.h>
504 #include <smime.h>
505 #include <ciferfam.h>
506 #ifdef HAVE_XCONST_H
507 #include <xconst.h>
508 #endif
509 #ifdef HAVE_GENNAME_H
510 #include <genname.h>
511 #endif
512 #include <private/pprio.h>
514 CERTAltNameEncodedContext foo;
518 if [ "${have_openssl}" = 'yes' ]; then
519 compile_check stack_of 'for STACK_OF()' \
520 '#define HAVE_STACK_OF' << \!
521 #include <openssl/ssl.h>
522 #include <openssl/err.h>
523 #include <openssl/x509v3.h>
524 #include <openssl/x509.h>
525 #include <openssl/rand.h>
527 int main(void)
529 STACK_OF(GENERAL_NAME) *gens = NULL;
530 printf("%p", gens); /* to make it used */
531 SSLv23_client_method();
532 PEM_read_PrivateKey(0, 0, 0, 0);
533 return 0;
538 else
539 echo '/* Socket/SSL support not desired */' >> $out
540 fi # wantfeat SSL
542 if wantfeat GSSAPI; then
543 cat >$tmp2.c <<\!
544 #include <gssapi/gssapi.h>
546 int main(void)
548 gss_import_name(0, 0, GSS_C_NT_HOSTBASED_SERVICE, 0);
549 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
550 return 0;
554 sed -e '1s/gssapi\///' < $tmp2.c > $tmp3.c
556 <$tmp2.c link_check gssapi 'for GSSAPI in libgss' \
557 '#define USE_GSSAPI' '-lgss' ||
558 <$tmp2.c link_check gssapi 'for GSSAPI in libgssapi_krb5' \
559 '#define USE_GSSAPI' '-lgssapi_krb5' ||
560 link_check gssapi 'for GSSAPI in libgssapi_krb5, old-style' \
561 '#define USE_GSSAPI
562 #define GSSAPI_OLD_STYLE' '-lgssapi_krb5' <<\! || \
563 <$tmp3.c link_check gssapi 'for GSSAPI in libgssapi' \
564 '#define USE_GSSAPI
565 #define GSSAPI_REG_INCLUDE' '-lgssapi' || \
566 <$tmp3.c link_check gssapi \
567 'for GSSAPI in libgssapi, OpenBSD-style' \
568 '#define USE_GSSAPI
569 #define GSSAPI_REG_INCLUDE' \
570 '-lgssapi -lkrb5 -lcrypto' '-I/usr/include/kerberosV'
572 #include <gssapi/gssapi.h>
573 #include <gssapi/gssapi_generic.h>
575 int main(void)
577 gss_import_name(0, 0, gss_nt_service_name, 0);
578 gss_init_sec_context(0,0,0,0,0,0,0,0,0,0,0,0,0);
579 return 0;
583 else
584 echo '/* IMAP/GSSAPI support not desired */' >> $out
585 fi # wantfeat GSSAPI
587 if wantfeat IDNA; then
588 link_check idna 'for GNU Libidn' '#define USE_IDNA' '-lidn' << \!
589 #include <idna.h>
590 #include <stringprep.h>
591 #include <tld.h>
593 int main(void)
595 char *utf8, *idna_ascii;
596 uint32_t *idna_uni;
597 size_t sz;
598 utf8 = stringprep_locale_to_utf8("does.this.work");
599 if (idna_to_ascii_8z(utf8, &idna_ascii, IDNA_USE_STD3_ASCII_RULES)
600 != IDNA_SUCCESS)
601 return (1);
602 if (idna_to_unicode_8z4z(idna_ascii, &idna_uni, 0) != IDNA_SUCCESS)
603 return (1 + (unsigned char)idna_strerror(0)[0]);
604 if (tld_check_4z(idna_uni, &sz, NULL) != TLD_SUCCESS)
605 return (2 + (unsigned char)tld_strerror(0)[0]);
606 return (0);
610 else
611 echo '/* IDNA support not desired */' >> $out
612 fi # wantfeat IDNA
614 if wantfeat JUNK; then
615 echo "#define USE_JUNK" >> $out
616 else
617 echo "/* #define USE_JUNK */" >> $out
620 if wantfeat MD5; then
621 echo "#define USE_MD5" >> $out
622 else
623 echo "/* #define USE_MD5 */" >> $out
626 if wantfeat ASSERTS; then
627 echo "#define HAVE_ASSERTS" >> $out
628 else
629 echo "/* #define HAVE_ASSERTS */" >> $out
632 # Since we cat(1) the content of those to cc/"ld", convert them to single line
633 squeeze_em() {
634 < "${1}" > "${2}" awk \
635 'BEGIN {ORS = " "} /^[^#]/ {print} {next} END {ORS = ""; print "\n"}'
637 rm -f "$tmp"
638 squeeze_em "$inc" "$tmp"
639 mv "$tmp" "$inc"
640 squeeze_em "$lib" "$tmp"
641 mv "$tmp" "$lib"
643 # Finished!
644 cat > $tmp2.c << \!
645 #include "config.h"
646 #ifdef HAVE_NL_LANGINFO
647 #include <langinfo.h>
648 #endif
650 :The following optional features are enabled:
651 #ifdef HAVE_SETLOCALE
652 : + Locale support: Printable characters depend on the environment
653 #if defined HAVE_MBTOWC && defined HAVE_WCTYPE_H
654 : + Multibyte character support
655 #endif
656 #endif
657 #ifdef HAVE_ICONV
658 : + Character set conversion using iconv()
659 #endif
660 #if defined HAVE_SETLOCALE && defined HAVE_NL_LANGINFO && defined CODESET
661 : + Automatic detection of terminal character set
662 #endif
663 #ifdef HAVE_SOCKETS
664 : + Network support
665 #endif
666 #ifdef USE_IPV6
667 : + Support for Internet Protocol v6 (IPv6)
668 #endif
669 #ifdef USE_NSS
670 : + S/MIME and SSL/TLS using Network Security Services (NSS)
671 #endif
672 #ifdef USE_OPENSSL
673 : + S/MIME and SSL/TLS using OpenSSL
674 #endif
675 #ifdef USE_IMAP
676 : + IMAP protocol
677 #endif
678 #ifdef USE_GSSAPI
679 : + IMAP GSSAPI authentication
680 #endif
681 #ifdef USE_POP3
682 : + POP3 protocol
683 #endif
684 #ifdef USE_SMTP
685 : + SMTP protocol
686 #endif
687 #ifdef USE_JUNK
688 : + Junk-mail management (Bayesian filtering)
689 #endif
690 #ifdef USE_MD5
691 : + The MD5 message digest
692 #endif
693 #ifdef USE_IDNA
694 : + IDNA (internationalized domain names for applications) support
695 #endif
697 :The following optional features are disabled:
698 #ifndef HAVE_SETLOCALE
699 : - Locale support: Only ASCII characters are recognized
700 #endif
701 #if ! defined HAVE_SETLOCALE || ! defined HAVE_MBTOWC || !defined HAVE_WCTYPE_H
702 : - Multibyte character support
703 #endif
704 #ifndef HAVE_ICONV
705 : - Character set conversion using iconv()
706 #endif
707 #if ! defined HAVE_SETLOCALE || ! defined HAVE_NL_LANGINFO || ! defined CODESET
708 : - Automatic detection of terminal character set
709 #endif
710 #ifndef HAVE_SOCKETS
711 : - Network support
712 #endif
713 #ifndef USE_IPV6
714 : - Support for Internet Protocol v6 (IPv6)
715 #endif
716 #if ! defined USE_SSL && ! defined USE_NSS
717 : - SSL/TLS (network transport authentication and encryption)
718 #endif
719 #ifndef USE_IMAP
720 : - IMAP protocol
721 #endif
722 #ifndef USE_GSSAPI
723 : - IMAP GSSAPI authentication
724 #endif
725 #ifndef USE_POP3
726 : - POP3 protocol
727 #endif
728 #ifndef USE_SMTP
729 : - SMTP protocol
730 #endif
731 #ifndef USE_JUNK
732 : - Junk-mail management (Bayesian filtering)
733 #endif
734 #ifndef USE_MD5
735 : - The MD5 message digest
736 #endif
737 #ifndef USE_IDNA
738 : - IDNA (internationalized domain names for applications) support
739 #endif
741 :Remarks:
742 #ifndef HAVE_SNPRINTF
743 : * The function snprintf() could not be found. mailx will be compiled to use
744 : sprintf() instead. This might overflow buffers if input values are larger
745 : than expected. Use the resulting binary with care or update your system
746 : environment and start the configuration process again.
747 #endif
748 #ifndef HAVE_FCHDIR
749 : * The function fchdir() could not be found. mailx will be compiled to use
750 : chdir() instead. This is not a problem unless the current working
751 : directory of mailx is moved while the IMAP cache is used.
752 #endif
753 #ifndef HAVE_GETOPT
754 : * A (usable) getopt() functionality could not be found.
755 : A builtin version is used instead.
756 #endif
757 #ifdef HAVE_ASSERTS
758 : * WANT_ASSERTS is enabled, the program binary will contain code assertions.
759 : There are also additional commands available, like "core".
760 : Such a binary is not meant to be used by end-users, but only for
761 : development purposes. Thanks!
762 #endif
766 $make -f $makefile $tmp2.x
767 < $tmp2.x >&5 sed '/^[^:]/d; /^$/d; s/^://'
769 exit 0