2 #@ Please see INSTALL and make.rc instead.
7 # For heaven's sake auto-redirect on SunOS/Solaris
8 if [ -z "${__MAKE_CONFIG_UP}" ] && [ -d /usr
/xpg4
]; then
10 PATH
=/usr
/xpg
4/bin
:${PATH}
11 export __MAKE_CONFIG_UP PATH
13 if [ "x${SHELL}" = x
] ||
[ "${SHELL}" = /bin
/sh
]; then
14 SHELL
=/usr
/xpg
4/bin
/sh
16 echo >&2 'SunOS/Solaris, redirecting through $SHELL=/usr/xpg4/bin/sh'
17 exec /usr
/xpg
4/bin
/sh
"${0}" "${@}"
21 if [ -z "${SHELL}" ]; then
26 # The feature set, to be kept in sync with make.rc
27 # If no documentation given, the option is used as such; if doc is '-',
28 # entry is suppressed when configuration overview is printed, and also in the
29 # *features* string: most likely for obsolete features etc.
31 CMD_CSOP='csop command: C-style string operations' \
32 CMD_VEXPR='vexpr command: evaluate arguments as expressions' \
33 COLOUR='Coloured message display' \
34 DOCSTRINGS='Command documentation help strings' \
35 DOTLOCK='Dotlock files and privilege-separated dotlock program' \
36 ERRORS='Log message ring' \
37 FILTER_HTML_TAGSOUP='Simple built-in HTML-to-text display filter' \
38 FILTER_QUOTE_FOLD='Extended *quote-fold*ing filter' \
39 ICONV='Character set conversion using iconv(3)' \
40 IDNA='Internationalized Domain Names for Applications (encode only)' \
41 IMAP_SEARCH='IMAP-style search expressions' \
42 MAILCAP='MIME type handlers defined via mailcap file(s)' \
43 MAILDIR='Maildir E-mail directories' \
44 MLE='Mailx Line Editor' \
45 HISTORY='Line editor history management' \
46 KEY_BINDINGS='Configurable key bindings' \
47 TERMCAP='Terminal capability queries (termcap(5))' \
48 TERMCAP_VIA_TERMINFO='Terminal capability queries use terminfo(5)' \
49 MTA_ALIASES='MTA aliases(5) (text file) support' \
50 REGEX='Regular expressions' \
51 NET='Network support' \
52 GSSAPI='Generic Security Service authentication' \
53 IMAP='IMAP v4r1 client' \
54 MD5='MD5 message digest (APOP, CRAM-MD5)' \
55 NETRC='.netrc file support' \
56 POP3='Post Office Protocol Version 3 client' \
57 SMTP='Simple Mail Transfer Protocol client' \
58 TLS='Transport Layer Security (OpenSSL / LibreSSL)' \
59 TLS_ALL_ALGORITHMS='Support of all digest and cipher algorithms' \
60 SPAM_FILTER='Freely configurable *spam-filter-..*s' \
61 SPAM_SPAMC='Spam management via spamc(1) of spamassassin(1)' \
62 UISTRINGS='User interface and error message strings' \
65 # Options which are automatically deduced from host environment, i.e., these
66 # need special treatment all around here to warp from/to OPT_ stuff
67 # setlocale, C90AMEND1, NL_LANGINFO, wcwidth
69 LOCALES='Locale support - printable characters etc. depend on environment' \
70 MULTIBYTE_CHARSETS='Multibyte character sets' \
71 TERMINAL_CHARSET='Automatic detection of terminal character set' \
72 WIDE_GLYPHS='Wide glyph support' \
75 # Rather special options, for custom building, or which always exist.
76 # Mostly for generating the visual overview and the *features* string
78 CROSS_BUILD='Cross-compilation: trust any detected environment' \
79 DEBUG='Debug enabled binary, not for end-users: THANKS!' \
80 DEVEL='Computers do not blunder' \
81 MIME='Multipurpose Internet Mail Extensions' \
82 SMIME='S/MIME message signing, verification, en- and decryption' \
85 # To avoid too many recompilations we use a two-stage "configuration changed"
86 # detection, the first uses mk-config.env, which only goes for actual user
87 # config settings etc. the second uses mk-config.h, which thus includes the
88 # things we have truly detected. This does not work well for multiple choice
89 # values of which only one will be really used, so those user wishes may not be
90 # placed in the header, only the really detected one (but that has to!).
91 # Used for grep(1), for portability assume fixed matching only.
92 H_BLACKLIST
='-e VAL_ICONV -e VAL_IDNA -e VAL_RANDOM'
94 # The problem is that we don't have any tools we can use right now, so
95 # encapsulate stuff in functions which get called in right order later on
102 [ -n "${j}" ] && eval SAVE_OPT_${i}=${j}
113 OPT_DOTLOCK=require OPT_ICONV=require OPT_REGEX=require
121 eval j=\$SAVE_OPT_${i}
122 if [ -n "${j}" ]; then
123 msg_nonl "${any}${i}=${j}"
128 [ -n "${any}" ] && msg_nonl ' ... '
132 option_parse OPTIONS_DETECT "${XOPTIONS_DETECT}"
133 option_parse OPTIONS "${XOPTIONS}"
134 option_parse OPTIONS_XTRA "${XOPTIONS_XTRA}"
137 # Predefined CONFIG= urations take precedence over anything else
138 if [ -n "${CONFIG}" ]; then
143 [nN][uU][lL][lL][iI])
147 [mM][iI][nN][iI][mM][aA][lL])
152 OPT_DOTLOCK=require OPT_ICONV=require OPT_REGEX=require
157 OPT_HISTORY=1 OPT_KEY_BINDINGS=1
161 [nN][eE][tT][sS][eE][nN][dD])
166 OPT_DOTLOCK=require OPT_ICONV=require OPT_REGEX=require
171 OPT_HISTORY=1 OPT_KEY_BINDINGS=1
181 [mM][aA][xX][iI][mM][aA][lL])
184 [dD][eE][vV][eE][lL])
186 OPT_DEVEL=1 OPT_DEBUG=1
188 [oO][dD][eE][vV][eE][lL])
194 msg 'ERROR: unknown CONFIG= setting: '${CONFIG}
195 msg ' Available are NULL, NULLI, MINIMAL, NETSEND, MAXIMAL'
199 msg_nonl "CONFIG
=${CONFIG} ...
"
204 # Inter-relationships XXX sort this!
207 OPT_TLS_ALL_ALGORITHMS=0
210 if feat_no SMTP && feat_no POP3 && feat_no IMAP; then
214 if feat_require IMAP; then
215 msg 'ERROR: need NETwork for required feature IMAP'
218 if feat_require POP3; then
219 msg 'ERROR: need NETwork for required feature POP3'
222 if feat_require SMTP; then
223 msg 'ERROR: need NETwork for required feature SMTP'
232 OPT_TLS=0 OPT_TLS_ALL_ALGORITHMS=0
234 if feat_no SMTP && feat_no IMAP; then
238 if feat_no ICONV; then
239 if feat_yes IMAP; then
240 if feat_yes ALWAYS_UNICODE_LOCALE; then
241 msg 'WARN: no ICONV, keeping IMAP due to ALWAYS_UNICODE_LOCALE!'
242 elif feat_require IMAP; then
243 msg 'ERROR: need ICONV for required feature IMAP'
246 msg 'ERROR: disabling IMAP due to missing ICONV'
251 if feat_yes IDNA; then
252 if feat_require IDNA; then
253 msg 'ERROR: need ICONV for required feature IDNA'
256 msg 'ERROR: disabling IDNA due to missing ICONV'
262 OPT_HISTORY=0 OPT_KEY_BINDINGS=0
263 OPT_TERMCAP=0 OPT_TERMCAP_VIA_TERMINFO=0
264 elif feat_no TERMCAP; then
265 OPT_TERMCAP_VIA_TERMINFO=0
269 ## -- >8 - << OPTIONS | EARLY >> - 8< -- ##
271 # Note that potential duplicates in PATH, C_INCLUDE_PATH etc. will be cleaned
272 # via path_check() later on once possible
276 # which(1) not standardized, command(1) -v may return non-executable: unroll!
277 SU_FIND_COMMAND_INCLUSION=1 . "${TOPDIR}"mk/su-find-command.sh
278 # Also not standardized: a way to round-trip quote
279 . "${TOPDIR}"mk/su-quote-rndtrip.sh
281 ## -- >8 - << EARLY | OS/CC >> - 8< -- ##
283 # TODO cc_maxopt is brute simple, we should compile test program and dig real
284 # compiler versions for known compilers, then be more specific
285 [ -n "${cc_maxopt}" ] || cc_maxopt=100
292 ld_rpath_not_runpath=
297 # We don't "have any utility
" (see make.rc)
298 [ -n "${OS}" ] && [ -n "${OSFULLSPEC}" ] ||
299 thecmd_testandset_fail uname uname
301 [ -n "${OS}" ] || OS=`${uname} -s`
303 msg 'Operating system is %s' "${OS}"
305 if [ ${OS} = SunOS ]; then
306 # According to standards(5), this is what we need to do
307 if [ -d /usr/xpg4 ]; then :; else
308 msg 'ERROR: On SunOS / Solaris we need /usr/xpg4 environment! Sorry.'
311 # xpg4/bin was already added at top, but we need it first and it will be
312 # cleaned up via path_check along the way
313 PATH="/usr
/xpg
4/bin
:/usr
/ccs
/bin
:/usr
/bin
:${PATH}"
314 [ -d /usr/xpg6 ] && PATH="/usr
/xpg
6/bin
:${PATH}"
320 # OSFULLSPEC is used to recognize changes (i.e., machine type, updates
321 # etc.), it is not baked into the binary
322 [ -n "${OSFULLSPEC}" ] || OSFULLSPEC=`${uname} -a`
324 if [ ${OS} = darwin ]; then
325 msg ' . have special Darwin environmental addons...'
326 LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${DYLD_LIBRARY_PATH}
327 elif [ ${OS} = sunos ]; then
328 msg ' . have special SunOS / Solaris "setup
" rules ...'
329 cc_os_search=_cc_os_sunos
331 elif [ ${OS} = unixware ]; then
332 cc_os_search=_cc_os_unixware
333 elif [ -n "${VERBOSE}" ]; then
334 msg ' . no special treatment for this system necessary or known'
337 # Sledgehammer: better set _GNU_SOURCE
338 # And in general: oh, boy!
339 OS_DEFINES="${OS_DEFINES}#define _GNU_SOURCE\n"
340 #OS_DEFINES="${OS_DEFINES}#define _POSIX_C_SOURCE 200809L\n"
341 #OS_DEFINES="${OS_DEFINES}#define _XOPEN_SOURCE 700\n"
342 #[ ${OS} = darwin ] && OS_DEFINES="${OS_DEFINES}#define _DARWIN_C_SOURCE\n"
344 # On pkgsrc(7) systems automatically add /usr/pkg/*
345 if feat_yes USE_PKGSYS
; then
346 if [ -d /usr
/pkg
]; then
347 msg
' . found pkgsrc(7), merging C_INCLUDE_PATH and LD_LIBRARY_PATH'
348 C_INCLUDE_PATH
=/usr
/pkg
/include
:${C_INCLUDE_PATH}
349 LD_LIBRARY_PATH
=/usr
/pkg
/lib
:${LD_LIBRARY_PATH}
350 ld_rpath_not_runpath
=1
356 C_INCLUDE_PATH
=/usr
/xpg
4/include
:${C_INCLUDE_PATH}
357 LD_LIBRARY_PATH
=/usr
/xpg
4/lib
:${LD_LIBRARY_PATH}
360 if feat_yes USE_PKGSYS
; then
361 if [ -d /opt
/csw
]; then
362 msg
' . found OpenCSW PKGSYS'
363 C_INCLUDE_PATH
=/opt
/csw
/include
:${C_INCLUDE_PATH}
364 LD_LIBRARY_PATH
=/opt
/csw
/lib
:${LD_LIBRARY_PATH}
365 ld_no_bind_now
=1 ld_rpath_not_runpath
=1
367 if [ -d /opt
/schily
]; then
368 msg
' . found Schily PKGSYS'
369 C_INCLUDE_PATH
=/opt
/schily
/include
:${C_INCLUDE_PATH}
370 LD_LIBRARY_PATH
=/opt
/schily
/lib
:${LD_LIBRARY_PATH}
371 ld_no_bind_now
=1 ld_rpath_not_runpath
=1
375 OS_DEFINES
="${OS_DEFINES}#define __EXTENSIONS__\n"
376 #OS_DEFINES="${OS_DEFINES}#define _POSIX_C_SOURCE 200112L\n"
378 msg
'Whatever $CC, turning off stack protection (see INSTALL)!'
379 cc_maxopt
=2 cc_no_stackprot
=1
383 # Check out compiler ($CC) and -flags ($CFLAGS)
385 # Even though it belongs into cc_flags we will try to compile and link
386 # something, so ensure we have a clean state regarding CFLAGS/LDFLAGS or
387 # EXTRA_CFLAGS/EXTRA_LDFLAGS
388 if feat_no AUTOCC
; then
390 # Ensure those don't do any harm
391 EXTRA_CFLAGS
= EXTRA_LDFLAGS
=
392 export CC EXTRA_CFLAGS EXTRA_LDFLAGS
396 export CFLAGS LDFLAGS
399 if [ -n "${CC}" ]; then
405 if [ -n "${cc_os_search}" ] && ${cc_os_search}; then
408 msg_nonl
'Searching for a usable C compiler .. $CC='
409 if acmd_set CC clang || acmd_set CC gcc ||
410 acmd_set CC tcc || acmd_set CC pcc ||
411 acmd_set CC c89 || acmd_set CC c99
; then
413 *pcc
*) cc_no_fortify
=1;;
417 msg
'boing booom tschak'
418 msg
'ERROR: I cannot find a compiler!'
419 msg
' Neither of clang(1), gcc(1), tcc(1), pcc(1), c89(1) and c99(1).'
420 msg
' Please set ${CC} environment variable, maybe ${CFLAGS}, rerun.'
429 if feat_yes AUTOCC
&& acmd_set CC cc
; then
430 msg_nonl
' . have special UnixWare rules for $CC ...'
431 feat_yes DEBUG
&& _CFLAGS
='-v -Xa -g' || _CFLAGS
='-Xa -O'
433 CFLAGS
="${_CFLAGS} ${EXTRA_CFLAGS}"
434 LDFLAGS
="${_LDFLAGS} ${EXTRA_LDFLAGS}"
435 export CC CFLAGS LDFLAGS
436 OPT_AUTOCC
=0 ld_need_R_flags
=-R
443 if feat_yes AUTOCC
&& acmd_set CC cc
&& "${CC}" -flags >/dev
/null
2>&1; then
444 msg_nonl
' . have special SunOS rules for $CC ...'
445 feat_yes DEBUG
&& _CFLAGS
="-v -Xa -g" || _CFLAGS
="-Xa -O"
447 CFLAGS
="${_CFLAGS} ${EXTRA_CFLAGS}"
448 LDFLAGS
="${_LDFLAGS} ${EXTRA_LDFLAGS}"
449 export CC CFLAGS LDFLAGS
450 OPT_AUTOCC
=0 ld_need_R_flags
=-R
454 : # cc_maxopt=2 cc_no_stackprot=1
460 if [ -z "${CC}" ]; then
461 msg
'To go on like you have chosen, please set $CC, rerun.'
465 if [ -z "${VERBOSE}" ] && [ -f ${env} ] && feat_no DEBUG
; then
468 msg
'Using C compiler ${CC}=%s' "${CC}"
472 *pcc
*) cc_no_fortify
=1;;
477 cc_create_testfile
() {
478 ${cat} > ${tmp}.c
<<\
!
481 static void doit
(char const
*s
);
483 main
(int argc
, char
**argv
){
492 memcpy
(buf
, s
, strlen
(s
) +1);
499 [ -n "${cc_check_silent}" ] || msg_nonl
' . CC compiles "Hello world" .. '
500 if ${CC} ${INCS} ${CFLAGS} ${EXTRA_CFLAGS} ${LDFLAGS} ${EXTRA_LDFLAGS} \
501 -o ${tmp2} ${tmp}.c ${LIBS}; then
502 [ -n "${cc_check_silent}" ] || msg
'yes'
503 feat_yes CROSS_BUILD
&& return 0
504 [ -n "${cc_check_silent}" ] || msg_nonl
' . Compiled program works .. '
505 if ( [ "`\"${tmp2}\"`" = 'Hello world' ] ) >/dev
/null
2>&1; then
506 [ -n "${cc_check_silent}" ] || msg
'yes'
510 [ -n "${cc_check_silent}" ] || msg
'no'
511 msg
'ERROR: i cannot compile or run a "Hello world" via'
513 "${CC} ${INCS} ${CFLAGS} ${EXTRA_CFLAGS} ${LDFLAGS} ${EXTRA_LDFLAGS} ${LIBS}"
514 msg
'ERROR: Please read INSTALL, rerun'
519 if [ -n "${cc_no_flagtest}" ]; then
520 ld_runtime_flags
# update!
521 elif feat_yes AUTOCC
; then
522 if [ -f ${env} ] && feat_no DEBUG
&& [ -z "${VERBOSE}" ]; then
524 msg
'Detecting ${CFLAGS}/${LDFLAGS} for ${CC}=%s, just a second..' \
528 msg
'Testing usable ${CFLAGS}/${LDFLAGS} for ${CC}=%s' "${CC}"
531 i=`echo "${CC}" | ${awk} 'BEGIN{FS="/"}{print $NF}'`
532 if { echo "${i}" | ${grep} tcc; } >/dev/null 2>&1; then
533 msg ' . have special tcc(1) environmental rules ...'
536 # As of pcc CVS 2016-04-02, stack protection support is announced but
537 # will break if used on Linux
538 #if { echo "${i}" | ${grep} pcc; } >/dev/null 2>&1; then
544 feat_no DEBUG && feat_no DEVEL && _CFLAGS="-DNDEBUG ${_CFLAGS}"
545 CFLAGS="${_CFLAGS} ${EXTRA_CFLAGS}"
546 LDFLAGS="${_LDFLAGS} ${EXTRA_LDFLAGS}"
548 if feat_no DEBUG && feat_no DEVEL; then
549 CFLAGS="-DNDEBUG ${CFLAGS}"
552 export CFLAGS LDFLAGS
556 __cflags=${_CFLAGS} __ldflags=${_LDFLAGS}
564 if feat_yes DEBUG; then
565 # May have problems to find libtcc cc_check -b
569 if ld_check -Wl,-rpath =./ no; then
570 ld_need_R_flags=-Wl,-rpath=
571 if [ -z "${ld_rpath_not_runpath}" ]; then
572 ld_check -Wl,--enable-new-dtags
574 msg ' ! $LD_LIBRARY_PATH adjusted, not trying --enable-new-dtags'
576 ld_runtime_flags # update!
579 _CFLAGS="${_CFLAGS} ${__cflags}" _LDFLAGS="${_LDFLAGS} ${__ldflags}"
580 unset __cflags __ldflags
583 _cc_flags_generic() {
584 __cflags=${_CFLAGS} __ldflags=${_LDFLAGS}
586 feat_yes DEVEL && cc_check -std=c89 || cc_check -std=c99
588 # E.g., valgrind does not work well with high optimization
589 if [ ${cc_maxopt} -gt 1 ] && feat_yes NOMEMDBG &&
590 feat_no ASAN_ADDRESS && feat_no ASAN_MEMORY; then
591 msg ' ! OPT_NOMEMDBG, setting cc_maxopt=1 (-O1)'
594 # Check -g first since some others may rely upon -g / optim. level
595 if feat_yes DEBUG; then
598 elif [ ${cc_maxopt} -gt 2 ] && cc_check -O3; then
600 elif [ ${cc_maxopt} -gt 1 ] && cc_check -O2; then
602 elif [ ${cc_maxopt} -gt 0 ] && cc_check -O1; then
608 if feat_yes AMALGAMATION; then
612 #if feat_yes DEVEL && cc_check -Weverything; then
618 if feat_yes DEVEL; then
619 cc_check -Wbad-function-cast
620 cc_check -Wcast-align
622 cc_check -Wformat-security # -Wformat via -Wall
623 cc_check -Wformat-signedness
625 cc_check -Wmissing-prototypes
628 cc_check -Wwrite-strings
629 cc_check -Wno-long-long
633 if feat_no DEVEL; then
634 if feat_yes AMALGAMATION; then
635 cc_check -Wno-unused-function
637 if cc_check -Wno-uninitialized; then :; else
638 cc_check -Wno-maybe-uninitialized
640 cc_check -Wno-unused-result
641 cc_check -Wno-unused-value
644 cc_check -fno-asynchronous-unwind-tables
646 cc_check -fno-unwind-tables
647 cc_check -fstrict-aliasing
648 if cc_check -fstrict-overflow && feat_yes DEVEL; then
649 cc_check -Wstrict-overflow=5
652 if feat_yes AUTOCC_STACKPROT; then
653 if [ -z "${cc_no_stackprot}" ]; then
654 if cc_check -fstack-protector-strong ||
655 cc_check -fstack-protector-all; then
656 if [ -z "${cc_no_fortify}" ]; then
657 cc_check -D_FORTIFY_SOURCE=2
659 msg ' ! Not checking for -D_FORTIFY_SOURCE=2 compiler option,'
660 msg ' ! since that caused errors in a "similar" configuration.'
661 msg ' ! You may turn off OPT_AUTOCC, then rerun with your own'
665 msg ' ! Not checking for -fstack-protector compiler option,'
666 msg ' ! since that caused errors in a "similar" configuration.'
667 msg ' ! You may turn off OPT_AUTOCC, then rerun with your own'
671 # LD (+ dependent CC)
673 if feat_yes ASAN_ADDRESS; then
675 if cc_check -fsanitize=address && ld_check -fsanitize=address; then
678 feat_bail_required ASAN_ADDRESS
683 if feat_yes ASAN_MEMORY; then
685 if cc_check -fsanitize=memory && ld_check -fsanitize=memory &&
686 cc_check -fsanitize-memory-track-origins=2 &&
687 ld_check -fsanitize-memory-track-origins=2; then
690 feat_bail_required ASAN_MEMORY
695 if feat_yes USAN; then
697 if cc_check -fsanitize=undefined && ld_check -fsanitize=undefined; then
700 feat_bail_required USAN
705 ld_check -Wl,-z,relro
706 if [ -z "${ld_no_bind_now}" ]; then
709 msg ' ! $LD_LIBRARY_PATH adjusted, not trying -Wl,-z,now'
711 ld_check -Wl,-z,noexecstack
712 ld_check -Wl,--as-needed
713 if ld_check -Wl,-rpath =./ no; then
714 ld_need_R_flags=-Wl,-rpath=
715 # Choose DT_RUNPATH (after $LD_LIBRARY_PATH) over DT_RPATH (before)
716 if [ -z "${ld_rpath_not_runpath}" ]; then
717 ld_check -Wl,--enable-new-dtags
719 msg ' ! $LD_LIBRARY_PATH adjusted, not trying --enable-new-dtags'
721 ld_runtime_flags # update!
722 elif ld_check -Wl,-R ./ no; then
723 ld_need_R_flags=-Wl,-R
724 if [ -z "${ld_rpath_not_runpath}" ]; then
725 ld_check -Wl,--enable-new-dtags
727 msg ' ! $LD_LIBRARY_PATH adjusted, not trying --enable-new-dtags'
729 ld_runtime_flags # update!
732 # Address randomization
734 if cc_check -fPIE || cc_check -fpie; then
735 ld_check -pie || _CFLAGS=${_ccfg}
739 # Retpoline (xxx maybe later?)
740 # _ccfg=${_CFLAGS} _i=
741 # if cc_check -mfunction-return=thunk; then
742 # if cc_check -mindirect-branch=thunk; then
745 # elif cc_check -mretpoline; then
748 # if [ -n "${_i}" ]; then
749 # ld_check -Wl,-z,retpolineplt || _i=
751 # [ -n "${_i}" ] || _CFLAGS=${_ccfg}
754 _CFLAGS="${_CFLAGS} ${__cflags}" _LDFLAGS="${_LDFLAGS} ${__ldflags}"
755 unset __cflags __ldflags
758 ## -- >8 - <<OS/CC | SUPPORT FUNS>> - 8< -- ##
761 ## - Heirloom sh(1) (and same origin) have _sometimes_ problems with ': >'
762 ## redirection, so use "printf '' >" instead
764 ## Very first: we undergo several states regarding I/O redirection etc.,
765 ## but need to deal with option updates from within all. Since all the
766 ## option stuff should be above the scissor line, define utility functions
767 ## and redefine them as necessary.
768 ## And, since we have those functions, simply use them for whatever
770 t1=ten10one1ten10one1
771 if ( [ ${t1##*ten10} = one1 ] && [ ${t1#*ten10} = one1ten10one1 ] &&
772 [ ${t1%%one1*} = ten10 ] && [ ${t1%one1*} = ten10one1ten10 ]
773 ) > /dev/null 2>&1; then
780 ( set -o noglob ) >/dev/null 2>&1 && noglob_shell=1 || unset noglob_shell
786 # Our feature check environment
790 [ "x${1}" = x0 ] || [ "x${1}" = xn ] ||
791 [ "x${1}" = xfalse ] || [ "x${1}" = xno ] || [ "x${1}" = xoff ]
795 [ "x${1}" = x1 ] || [ "x${1}" = xy ] ||
796 [ "x${1}" = xtrue ] || [ "x${1}" = xyes ] || [ "x${1}" = xon ] ||
797 [ "x${1}" = xrequire ]
800 _feat_val_require() {
801 [ "x${1}" = xrequire ]
805 eval _fc_i=\$OPT_${1}
806 if [ "$_feats_eval_done" = 1 ]; then
807 [ "x${_fc_i}" = x0 ] && return 1
810 _fc_i="`echo ${_fc_i} |
${tr} '[A-Z]' '[a-z]'`"
811 if _feat_val_no "${_fc_i}"; then
813 elif _feat_val_yes "${_fc_i}"; then
816 msg "ERROR: %s: 0/n/false/no/off or 1/y/true/yes/on/require, got: %s" \
827 _feat_check ${1} && return 1
832 eval _fr_i=\$OPT_${1}
833 _fr_i="`echo ${_fr_i} |
${tr} '[A-Z]' '[a-z]'`"
834 [ "x${_fr_i}" = xrequire ] || [ "x${_fr_i}" = xrequired ]
837 feat_bail_required() {
838 if feat_require ${1}; then
839 msg 'ERROR: feature OPT_%s is required but not available' "${1}"
842 feat_is_unsupported "${1}"
846 [ ${#} -eq 1 ] && msg ' . (disabled: OPT_%s)' "${1}"
847 echo "/* OPT_${1} -> mx_HAVE_${1} */" >> ${h}
850 feat_is_unsupported() {
851 msg ' ! NOTICE: unsupported: OPT_%s' "${1}"
852 echo "/* OPT_${1} -> mx_HAVE_${1} */" >> ${h}
854 option_update # XXX this is rather useless here (dependency chain..)
858 if feat_yes ${1}; then
859 [ -n "${VERBOSE}" ] && msg ' . %s ... yes' "${1}"
860 echo '#define mx_HAVE_'${1}'' >> ${h}
863 feat_is_disabled "${@}"
869 # Parse one of our XOPTIONS* in $2 and assign the sh(1) compatible list of
870 # options, without documentation, to $1
872 i="`${awk} -v input
=\"${2}\" '
875 voff = match(input, /[0-9a-zA-Z_]+(='${j}'[^'${j}']+)?/)
878 v = substr(input, voff, RLENGTH)
879 input = substr(input, voff + RLENGTH)
882 d = substr(v, doff + 2, length(v) - doff - 1)
883 v = substr(v, 1, doff - 1)
893 # Return the "documentation string" for option $1, itself if none such
895 ${awk} -v want="${1}" \
896 -v input="${XOPTIONS_DETECT}${XOPTIONS}${XOPTIONS_XTRA}" '
899 voff = match(input, /[0-9a-zA-Z_]+(='${j}'[^'${j}']+)?/)
902 v = substr(input, voff, RLENGTH)
903 input = substr(input, voff + RLENGTH)
906 d = substr(v, doff + 2, length(v) - doff - 1)
907 v = substr(v, 1, doff - 1)
921 # Join the values from make.rc into what currently is defined, not
922 # overwriting yet existing settings
924 # We want read(1) to perform reverse solidus escaping in order to be able to
925 # use multiline values in make.rc; the resulting sh(1)/sed(1) code was very
926 # slow in VMs (see [fa2e248]), Aharon Robbins suggested the following
927 < ${rc} ${awk} 'BEGIN{line = ""}{
930 if(sub(/\\$/, "", $0)){
935 if(index(line, "#") == 1){
937 }else if(length(line)){
943 if [ -n "${good_shell}" ]; then
946 i=`${awk} -v LINE
="${line}" 'BEGIN{
947 sub(/=.*$/, "", LINE)
951 if [ "${i}" = "${line}" ]; then
952 msg 'ERROR: invalid syntax in: %s' "${line}"
956 eval j="\$${i}" jx="\${${i}+x}"
957 if [ -n "${j}" ] || [ "${jx}" = x ]; then
960 j=`${awk} -v LINE
="${line}" 'BEGIN{
961 sub(/^[^=]*=/, "", LINE)
964 # Sun xpg4/bin/awk expands those twice:
965 # Notice that backslash escapes are interpreted twice, once in
966 # lexical processing of the string and once in processing the
967 # regular expression.
969 gsub(/"/, "\\\\\"", i)
971 gsub(/"/, (i ? "\\\\\"" : "\134\""), LINE)
975 [ "${i}" = "DESTDIR" ] && continue
976 [ "${i}" = "OBJDIR" ] && continue
979 # Reread the mixed version right now
984 # Expand the option values, which may contain shell snippets
985 # Set booleans to 0 or 1, or require, set _feats_eval_done=1
986 ${rm} -f ${newenv} ${newmk}
988 exec 7<&0 8>&1 <${tmp} >${newenv}
991 if [ -n "${good_shell}" ]; then
993 [ "${i}" != "${i#OPT_}" ] && z=1
995 i=`${awk} -v LINE
="${line}" 'BEGIN{
996 gsub(/=.*$/, "", LINE);\
999 if echo "${i}" | ${grep} '^OPT_' >/dev/null 2>&1; then
1005 if [ -n "${z}" ]; then
1006 j="`echo ${j} |
${tr} '[A-Z]' '[a-z]'`"
1007 if [ -z "${j}" ] || _feat_val_no "${j}"; then
1009 printf " /* #undef ${i} */\n" >> ${newh}
1010 elif _feat_val_yes "${j}"; then
1011 if _feat_val_require "${j}"; then
1016 printf " /* #define ${i} */\n" >> ${newh}
1018 msg 'ERROR: cannot parse <%s>' "${line}"
1021 elif { echo ${i} | ${grep} ${H_BLACKLIST} >/dev/null 2>&1; }; then
1024 printf "#define ${i} \"${j}\"\n" >> ${newh}
1026 printf -- "${i} = ${j}\n" >> ${newmk}
1027 printf -- "${i}=%s;export ${i}\n" "`quote_string ${j}`"
1028 eval "${i}=\"${j}\""
1030 exec 0<&7 1>&8 7<&- 8<&-
1036 eval __expo__=\$${1}
1037 ${awk} -v HEAP="${2}" -v USER="${__expo__}" '
1039 i = split(HEAP, ha, /[, ]/)
1040 if((j = split(USER, ua, /[, ]/)) == 0)
1044 if(us == "all" || us == "any")
1047 for(ii = i; ii != 0; --ii)
1048 if(tolower(ha[ii]) == us){
1058 [ ${__rv__} -ne 0 ] && return ${__rv__}
1060 if ${awk} -v USER
="${__expo__}" '
1062 if((j = split(USER, ua, /[, ]/)) == 0)
1066 if(us == "all" || us == "any")
1072 eval "${1}"=\"${2}\"
1074 # Enforce lowercase also in otherwise unchanged user value..
1075 eval "${1}"=\""`echo ${__expo__} | ${tr} '[A-Z]_' '[a-z]-'`"\"
1081 </dev
/null
${awk} -v X
="${1}" '
1085 X = substr(X, 1, RSTART - 1)
1092 path_is_absolute
() {
1093 { echo "${*}" | ${grep} ^/; } >/dev/null 2>&1
1098 # "path_check VARNAME
" or "path_check VARNAME FLAG VARNAME
"
1099 varname=${1} addflag=${2} flagvarname=${3}
1102 [ -n "${noglob_shell}" ] && set -o noglob
1103 eval "set -- \$
${1}"
1104 [ -n "${noglob_shell}" ] && set +o noglob
1109 [ -z "${i}" ] && continue
1110 [ -d "${i}" ] || continue
1111 if [ -n "${j}" ]; then
1112 if { z=${y}; echo "${z}"; } | ${grep} ":${i}:" >/dev
/null
2>&1; then
1117 # But do not link any fakeroot path into our binaries!
1118 if [ -n "${addflag}" ]; then
1119 case "${i}" in *fakeroot
*) continue;; esac
1120 k
="${k} ${addflag}${i}"
1126 # But do not link any fakeroot injected path into our binaries!
1127 if [ -n "${addflag}" ]; then
1128 case "${i}" in *fakeroot
*) continue;; esac
1129 k
="${k} ${addflag}${i}"
1133 eval "${varname}=\"${j}\""
1134 [ -n "${addflag}" ] && eval "${flagvarname}=\"${k}\""
1138 ld_runtime_flags
() {
1139 if [ -n "${ld_need_R_flags}" ]; then
1142 set -- ${LD_LIBRARY_PATH}
1146 # But do not link any fakeroot injected path into our binaries!
1147 case "${i}" in *fakeroot
*) continue;; esac
1148 LDFLAGS
="${LDFLAGS} ${ld_need_R_flags}${i}"
1149 _LDFLAGS
="${_LDFLAGS} ${ld_need_R_flags}${i}"
1153 # Disable it for a possible second run.
1157 _cc_check_ever
= _cc_check_testprog
=
1159 if [ -z "${_cc_check_ever}" ]; then
1161 __occ
=${cc_check_silent}
1162 __oCFLAGS
=${_CFLAGS}
1165 if cc_check
-Werror; then
1166 _cc_check_ever
=-Werror
1167 _CFLAGS
=${__oCFLAGS}
1168 # Overcome a _GNU_SOURCE related glibc 2.32.3 bug (?!)
1169 if cc_check
-Werror=implicit-function-declaration
; then
1170 _cc_check_testprog
=-Werror=implicit-function-declaration
1174 _CFLAGS
=${__oCFLAGS}
1175 cc_check_silent
=${__occ}
1176 unset __occ __oCFLAGS
1179 [ -n "${cc_check_silent}" ] || msg_nonl
' . CC %s .. ' "${1}"
1181 trap "exit 11" ABRT BUS ILL SEGV
# avoid error messages (really)
1182 ${CC} ${INCS} ${_cc_check_ever} \
1183 ${_CFLAGS} ${1} ${EXTRA_CFLAGS} ${_LDFLAGS} ${EXTRA_LDFLAGS} \
1184 -o ${tmp2} ${tmp}.c ${LIBS} ||
exit 1
1185 feat_no CROSS_BUILD ||
exit 0
1188 if [ $?
-eq 0 ]; then
1189 _CFLAGS
="${_CFLAGS} ${1}"
1190 [ -n "${cc_check_silent}" ] || msg
'yes'
1193 [ -n "${cc_check_silent}" ] || msg
'no'
1198 # $1=option [$2=option argument] [$3=if set, shall NOT be added to _LDFLAGS]
1199 [ -n "${cc_check_silent}" ] || msg_nonl
' . LD %s .. ' "${1}"
1201 trap "exit 11" ABRT BUS ILL SEGV
# avoid error messages (really)
1202 ${CC} ${INCS} ${_cc_check_ever} \
1203 ${_CFLAGS} ${_LDFLAGS} ${1}${2} ${EXTRA_LDFLAGS} \
1204 -o ${tmp2} ${tmp}.c ${LIBS} ||
exit 1
1205 feat_no CROSS_BUILD ||
exit 0
1208 if [ $?
-eq 0 ]; then
1209 [ -n "${3}" ] || _LDFLAGS="${_LDFLAGS} ${1}"
1210 [ -n "${cc_check_silent}" ] || msg
'yes'
1213 [ -n "${cc_check_silent}" ] || msg
'no'
1219 variable
=$1 topic
=$2 define
=$3
1222 msg_nonl
' . %s ... ' "${topic}"
1223 #echo "/* checked ${topic} */" >> ${h}
1224 ${rm} -f ${tmp} ${tmp}.o
1225 if [ "${dump_test_program}" = 1 ]; then
1226 { echo '#include <'"${h_name}"'>'; cat; } | ${tee} ${tmp}.c
1228 { echo '#include <'"${h_name}"'>'; cat; } > ${tmp}.c
1231 #MAKEFLAGS= ${make} -f ${makefile} ${tmp}.x
1237 oneorzero=$1 variable=$2 topic=$3 define=$4 libs=$5 incs=$6
1240 msg_nonl ' . %s ... ' "${topic}"
1242 if [ "${oneorzero}" = 1 ]; then
1243 if [ -n "${incs}" ] || [ -n "${libs}" ]; then
1244 echo "@ INCS
<${incs}> LIBS
<${libs}>"
1245 LIBS="${LIBS} ${libs}"
1246 INCS="${INCS} ${incs}"
1249 echo "${define}" >> ${h}
1250 eval have_${variable}=yes
1253 #echo "/* ${define} */" >> ${h}
1255 eval unset have_${variable}
1261 variable=$1 topic=$2 define=$3
1263 _check_preface "${variable}" "${topic}" "${define}"
1265 if MAKEFLAGS= ${make} -f ${makefile} XINCS="${INCS}" \
1266 CFLAGS
="${_cc_check_testprog} ${CFLAGS}" \
1267 LDFLAGS
="${_cc_check_testprog} ${LDFLAGS}" ${tmp}.o &&
1268 [ -f ${tmp}.o ]; then
1270 echo "${define}" >> ${h}
1271 eval have_${variable}=yes
1274 #echo "/* ${define} */" >> ${h}
1276 eval unset have_${variable}
1282 run=$1 variable=$2 topic=$3 define=$4 libs=$5 incs=$6
1284 _check_preface "${variable}" "${topic}" "${define}"
1286 if feat_yes CROSS_BUILD; then
1287 if [ ${run} = 1 ]; then
1292 if MAKEFLAGS= ${make} -f ${makefile} XINCS="${INCS} ${incs}" \
1293 CFLAGS
="${_cc_check_testprog} ${CFLAGS}" \
1294 LDFLAGS
="${_cc_check_testprog} ${LDFLAGS}" \
1295 XLIBS
="${LIBS} ${libs}" ${tmp} &&
1296 [ -f ${tmp} ] && { [ ${run} -eq 0 ] || ${tmp}; }; then
1297 echo "@ INCS
<${incs}> LIBS<${libs}>; executed: ${run}"
1299 echo "${define}" >> ${h}
1300 LIBS="${LIBS} ${libs}"
1301 INCS="${INCS} ${incs}"
1302 eval have_${variable}=yes
1306 #echo "/* ${define} */" >> ${h}
1307 eval unset have_${variable}
1313 _link_mayrun 0 "${1}" "${2}" "${3}" "${4}" "${5}"
1317 _link_mayrun 1 "${1}" "${2}" "${3}" "${4}" "${5}"
1321 _link_mayrun 2 "${1}" "${2}" "${3}" "${4}" "${5}"
1324 string_to_char_array() {
1325 ${awk} -v xy="${@}" 'BEGIN{
1326 # POSIX: unspecified behaviour.
1327 # Does not work for SunOS /usr/xpg4/bin/awk!
1328 if(split("abc
", xya, "") == 3)
1329 i = split(xy, xya, "")
1332 for(i = 0; j > 0; --j){
1333 xya[++i] = substr(xy, 1, 1)
1338 for(j = 1; j <= i; ++j){
1346 printf "'"'"'%s'"'"'", y
1353 ${sed} -e 's/^[ ]\{1,\}//' -e 's/[ ]\{1,\}$//' -e 's/[ ]\{1,\}/ /g'
1356 ## -- >8 - <<SUPPORT FUNS | RUNNING>> - 8< -- ##
1361 printf -- "${fmt}\n" "${@}"
1367 printf -- "${fmt}" "${@}"
1370 # Very easy checks for the operating system in order to be able to adjust paths
1371 # or similar very basic things which we need to be able to go at all
1374 # Check those tools right now that we need before including $rc
1375 msg 'Checking for basic utility set'
1376 thecmd_testandset_fail awk awk
1377 thecmd_testandset_fail rm rm
1378 thecmd_testandset_fail tr tr
1380 # Lowercase this now in order to isolate all the remains from case matters
1382 OS=`echo ${OS} | ${tr} '[A-Z]' '[a-z]'`
1385 # But first of all, create new configuration and check whether it changed
1386 if [ -z "${OBJDIR}" ]; then
1389 OBJDIR=`${awk} -v input="${OBJDIR}" 'BEGIN{
1390 if(index(input, "/"))
1391 sub("/+$
", "", input)
1397 env="${OBJDIR}"/mk-config.env
1398 h="${OBJDIR}"/mk-config.h h_name=mk-config.h
1399 mk="${OBJDIR}"/mk-config.mk
1401 newmk="${OBJDIR}"/mk-nconfig.mk
1402 oldmk="${OBJDIR}"/mk-oconfig.mk
1403 newenv="${OBJDIR}"/mk-nconfig.env
1404 newh="${OBJDIR}"/mk-nconfig.h
1405 oldh="${OBJDIR}"/mk-oconfig.h
1406 tmp0="${OBJDIR}"/___tmp
1410 if [ -d "${OBJDIR}" ] || mkdir -p "${OBJDIR}"; then :; else
1411 msg 'ERROR: cannot create '"${OBJDIR}"' build directory'
1416 log="${OBJDIR}"/mk-config.log
1417 exec 5>&2 > ${log} 2>&1
1422 printf -- "${fmt}\n" "${@}"
1423 printf -- "${fmt}\n" "${@}" >&5
1429 printf -- "${fmt}" "${@}"
1430 printf -- "${fmt}" "${@}" >&5
1433 # Initialize the option set
1434 msg_nonl 'Setting up configuration options ... '
1438 # Include $rc, but only take from it what wasn't overwritten by the user from
1439 # within the command line or from a chosen fixed CONFIG=
1440 # Note we leave alone the values
1441 trap "exit 1" HUP INT TERM
1442 trap "${rm} -f ${tmp}" EXIT
1444 msg_nonl 'Joining in %s ... ' ${rc}
1448 # We need to know about that now, in order to provide utility overwrites etc.
1451 msg 'Checking for remaining set of utilities'
1452 thecmd_testandset_fail getconf getconf
1453 thecmd_testandset_fail grep grep
1455 # Before we step ahead with the other utilities perform a path cleanup first.
1459 thecmd_testandset_fail basename basename
1460 thecmd_testandset_fail cat cat
1461 thecmd_testandset_fail chmod chmod
1462 thecmd_testandset_fail cp cp
1463 thecmd_testandset_fail cmp cmp
1465 thecmd_testandset ln ln # only for tests
1466 thecmd_testandset_fail mkdir mkdir
1467 thecmd_testandset_fail mv mv
1468 # We always need pwd(1), for at least mx-test.sh
1469 thecmd_testandset_fail pwd pwd
1471 thecmd_testandset_fail sed sed
1472 thecmd_testandset_fail sort sort
1473 thecmd_testandset_fail tee tee
1475 thecmd_testandset chown chown ||
1476 PATH="/sbin
:${PATH}" thecmd_set chown chown ||
1477 PATH="/usr
/sbin
:${PATH}" thecmd_set_fail chown chown
1479 thecmd_testandset_fail MAKE make
1482 thecmd_testandset strip strip
1484 # For ./mx-test.sh only
1485 thecmd_testandset_fail cksum cksum
1487 # Update OPT_ options now, in order to get possible inter-dependencies right
1490 # (No functions since some shells loose non-exported variables in traps)
1491 trap "trap \"\" HUP INT TERM
; exit 1" HUP INT TERM
1492 trap "trap \"\" HUP INT TERM EXIT
;\
1493 ${rm} -rf ${tmp0}.* ${tmp0}* \
1494 ${newmk} ${oldmk} ${newenv} ${newh} ${oldh}" EXIT
1496 printf '#ifdef mx_SOURCE\n' > ${newh}
1498 # Now that we have pwd(1) and options at least permit some more actions, set
1499 # our build paths unless make-emerge.sh has been used; it would have created
1500 # a makefile with the full paths otherwise
1501 if [ -z "${CWDDIR}" ]; then
1503 CWDDIR=`oneslash "${CWDDIR}"`
1505 if [ -z "${TOPDIR}" ]; then
1508 INCDIR="${TOPDIR}"include/
1509 SRCDIR="${TOPDIR}"src/
1514 PS_DOTLOCK_CWDDIR=${CWDDIR}
1515 PS_DOTLOCK_INCDIR=${INCDIR}
1516 PS_DOTLOCK_SRCDIR=${SRCDIR}
1521 # Our configuration options may at this point still contain shell snippets,
1522 # we need to evaluate them in order to get them expanded, and we need those
1523 # evaluated values not only in our new configuration file, but also at hand..
1524 msg_nonl 'Evaluating all configuration items ... '
1529 printf "#define VAL_UAGENT \"${VAL_SID}${VAL_MAILX}\"\n" >> ${newh}
1530 printf "VAL_UAGENT = ${VAL_SID}${VAL_MAILX}\n" >> ${newmk}
1531 printf "VAL_UAGENT
=${VAL_SID}${VAL_MAILX};export VAL_UAGENT\n" >> ${newenv}
1533 # The problem now is that the test should be able to run in the users linker
1534 # and path environment, so we need to place the test: rule first, before
1535 # injecting the relevant make variables. Set up necessary environment
1536 if [ -z "${VERBOSE}" ]; then
1537 printf -- "ECHO_CC = @echo ' 'CC \$(@);\n" >> ${newmk}
1538 printf -- "ECHO_LINK = @echo ' 'LINK \$(@);\n" >> ${newmk}
1539 printf -- "ECHO_GEN = @echo ' 'GEN \$(@);\n" >> ${newmk}
1540 printf -- "ECHO_TEST = @\n" >> ${newmk}
1541 printf -- "ECHO_CMD = @echo ' CMD';\n" >> ${newmk}
1543 printf 'test: all\n\t$(ECHO_TEST)%s %smx-test.sh --check %s\n' \
1544 "${SHELL}" "${TOPDIR}" "./${VAL_SID}${VAL_MAILX}" >> ${newmk}
1546 'testnj: all\n\t$(ECHO_TEST)%s %smx-test.sh --no-jobs --check %s\n' \
1547 "${SHELL}" "${TOPDIR}" "./${VAL_SID}${VAL_MAILX}" >> ${newmk}
1549 # Add the known utility and some other variables
1550 printf "#define VAL_PS_DOTLOCK \"${VAL_SID}${VAL_MAILX}-dotlock\"\n" >> ${newh}
1551 printf "VAL_PS_DOTLOCK
= \$
(VAL_UAGENT
)-dotlock\n" >> ${newmk}
1552 printf 'VAL_PS_DOTLOCK=%s;export VAL_PS_DOTLOCK\n' \
1553 "${VAL_SID}${VAL_MAILX}-dotlock" >> ${newenv}
1554 if feat_yes DOTLOCK
; then
1555 printf "#real below OPTIONAL_PS_DOTLOCK = \$(VAL_PS_DOTLOCK)\n" >> ${newmk}
1559 CWDDIR TOPDIR OBJDIR INCDIR SRCDIR \
1560 MX_CWDDIR MX_INCDIR MX_SRCDIR \
1561 PS_DOTLOCK_CWDDIR PS_DOTLOCK_INCDIR PS_DOTLOCK_SRCDIR \
1562 SU_CWDDIR SU_INCDIR SU_SRCDIR \
1563 awk basename cat chmod chown
cp cmp grep getconf \
1564 ln mkdir
mv pwd rm sed sort tee tr \
1565 MAKE MAKEFLAGS
make SHELL strip \
1568 printf -- "${i} = ${j}\n" >> ${newmk}
1569 printf -- "${i}=%s;export ${i}\n" "`quote_string ${j}`" >> ${newenv}
1572 # Build a basic set of INCS and LIBS according to user environment.
1573 C_INCLUDE_PATH
="${INCDIR}:${SRCDIR}:${C_INCLUDE_PATH}"
1574 if path_is_absolute
"${OBJDIR}"; then
1575 C_INCLUDE_PATH
="${OBJDIR}:${C_INCLUDE_PATH}"
1577 C_INCLUDE_PATH
="${CWDDIR}${OBJDIR}:${C_INCLUDE_PATH}"
1579 C_INCLUDE_PATH
="${CWDDIR}include:${C_INCLUDE_PATH}"
1581 path_check C_INCLUDE_PATH
-I _INCS
1582 INCS
="${INCS} ${_INCS}"
1583 path_check LD_LIBRARY_PATH
-L _LIBS
1584 LIBS
="${LIBS} ${_LIBS}"
1586 export C_INCLUDE_PATH LD_LIBRARY_PATH
1588 # Some environments need runtime path flags to be able to go at all
1591 ## Detect CC, whether we can use it, and possibly which CFLAGS we can use
1596 # This may also update ld_runtime_flags() (again)
1601 PATH C_INCLUDE_PATH LD_LIBRARY_PATH \
1607 printf -- "${i}=%s;export ${i}\n" "`quote_string ${j}`" >> ${newenv}
1610 # Now finally check whether we already have a configuration and if so, whether
1611 # all those parameters are still the same.. or something has actually changed
1613 if [ -f ${env} ] && ${cmp} ${newenv} ${env} >/dev/null 2>&1; then
1614 msg 'Configuration is up-to-date'
1616 elif [ -f ${env} ]; then
1618 msg 'Configuration has been updated..'
1620 msg 'Shiny configuration..'
1623 ### WE ARE STARTING OVER ###
1625 # Time to redefine helper 1
1631 ${mv} -f ${newenv} ${env}
1632 [ -f ${h} ] && ${mv} -f ${h} ${oldh}
1633 ${mv} -f ${newh} ${h} # Note this has still #ifdef mx_SOURCE open
1634 [ -f ${mk} ] && ${mv} -f ${mk} ${oldmk}
1635 ${mv} -f ${newmk} ${mk}
1637 ## Compile and link checking
1642 # (No function since some shells loose non-exported variables in traps)
1643 trap "trap \"\" HUP INT TERM
;\
1644 ${rm} -f ${oldh} ${h} ${oldmk} ${mk}; exit 1" \
1646 trap "trap \"\" HUP INT TERM EXIT
;\
1647 ${rm} -rf ${oldh} ${oldmk} ${tmp0}.* ${tmp0}*" EXIT
1649 # Time to redefine helper 2
1653 printf "@
${fmt}\n" "${@}"
1654 printf -- "${fmt}\n" "${@}" >&5
1659 printf "@
${fmt}\n" "${@}"
1660 printf -- "${fmt}" "${@}" >&5
1664 ${cat} > ${makefile} << \!
1665 .SUFFIXES: .o .c .x .y
1667 $(CC) -Dmx_SOURCE -I./ $(XINCS) $(CFLAGS) -o $(@) -c $(<)
1669 $(CC) -Dmx_SOURCE -I./ $(XINCS) -E $(<) > $(@)
1671 $(CC) -Dmx_SOURCE -I./ $(XINCS) $(CFLAGS) $(LDFLAGS) -o $(@) $(<) $(XLIBS)
1676 echo '#define VAL_BUILD_OS "'"${OS_ORIG_CASE}"'"' >> ${h}
1678 printf '#endif /* mx_SOURCE */\n\n' >> ${h} # Opened when it was $newh
1680 [ -n "${OS_DEFINES}" ] && printf \
1681 '#if defined mx_SOURCE || defined mx_EXT_SOURCE || defined su_SOURCE
1683 #endif /* mx_SOURCE || mx_EXT_SOURCE || su_SOURCE */
1689 i=`${getconf} PAGESIZE 2>/dev/null`
1690 [ $? -eq 0 ] || i=`${getconf} PAGE_SIZE 2>/dev/null`
1691 if [ $? -ne 0 ]; then
1692 msg 'Cannot query PAGESIZE via getconf(1), assuming 4096'
1695 printf '#define su_PAGE_SIZE %su\n' "${i}" >> ${h}
1697 # Generate SU <> OS error number mappings
1698 msg_nonl ' . OS error mapping table generated ... '
1699 feat_yes DEVEL && NV= || NV=noverbose
1700 SRCDIR="${SRCDIR}" TARGET="${h}" awk="${awk}" rm="${rm}" sort="${sort}" \
1701 ${SHELL} "${TOPDIR}"mk/su-make-errors.sh ${NV} compile_time || {
1709 ## Test for "basic
" system-calls / functionality that is used by all parts
1710 ## of our program. Once this is done fork away BASE_LIBS and other BASE_*
1711 ## macros to be used by only the subprograms (potentially).
1713 if run_check clock_gettime 'clock_gettime(2)' \
1714 '#define mx_HAVE_CLOCK_GETTIME' << \!
1720 if(!clock_gettime(CLOCK_REALTIME, &ts) || errno != ENOSYS)
1727 elif run_check clock_gettime 'clock_gettime(2) (via -lrt)' \
1728 '#define mx_HAVE_CLOCK_GETTIME' '-lrt' << \!
1734 if(!clock_gettime(CLOCK_REALTIME, &ts) || errno != ENOSYS)
1741 elif run_check gettimeofday 'gettimeofday(2)' \
1742 '#define mx_HAVE_GETTIMEOFDAY' << \!
1743 #include <stdio.h> /* For C89 NULL */
1744 #include <sys/time.h>
1749 if(!gettimeofday(&tv, NULL) || errno != ENOSYS)
1757 have_no_subsecond_time=1
1760 if run_check nanosleep 'nanosleep(2)' \
1761 '#define mx_HAVE_NANOSLEEP' << \!
1768 ts.tv_nsec = 100000;
1769 if(!nanosleep(&ts, NULL) || errno != ENOSYS)
1776 elif run_check nanosleep 'nanosleep(2) (via -lrt)' \
1777 '#define mx_HAVE_NANOSLEEP' '-lrt' << \!
1784 ts.tv_nsec = 100000;
1785 if(!nanosleep(&ts, NULL) || errno != ENOSYS)
1792 # link_check is enough for this, that function is so old, trust the proto
1793 elif link_check sleep 'sleep(3)' \
1794 '#define mx_HAVE_SLEEP' << \!
1798 if(!sleep(1) || errno != ENOSYS)
1806 msg 'ERROR: we require one of nanosleep(2) and sleep(3).'
1810 if run_check userdb 'gete?[gu]id(2), getpwuid(3), getpwnam(3)' << \!
1819 if((gid = getgid()) != 0)
1821 if((uid = getuid()) != 0)
1823 if((pw = getpwuid(uid)) == NULL && errno == ENOSYS)
1825 if((pw = getpwnam("root
")) == NULL && errno == ENOSYS)
1833 msg 'ERROR: we require user and group info / database searches.'
1834 msg 'That much Unix we indulge ourselves.'
1838 if link_check ftruncate 'ftruncate(2)' \
1839 '#define mx_HAVE_FTRUNCATE' << \!
1841 #include <sys/types.h>
1843 return (ftruncate(0, 0) != 0);
1849 # TODO support mx_HAVE_FTRUNCATE *everywhere*, do not require this syscall!
1850 msg 'ERROR: we require the ftruncate(2) system call.'
1854 if run_check sa_restart 'SA_RESTART (for sigaction(2))' << \!
1858 struct sigaction nact, oact;
1860 nact.sa_handler = SIG_DFL;
1861 sigemptyset(&nact.sa_mask);
1862 nact.sa_flags = SA_RESTART;
1863 return !(!sigaction(SIGCHLD, &nact, &oact) || errno != ENOSYS);
1869 msg 'ERROR: we (yet) require the SA_RESTART flag for sigaction(2).'
1873 if link_check snprintf 'snprintf(3)' << \!
1878 snprintf(b, sizeof b, "%s
", "string
");
1885 msg 'ERROR: we require the snprintf(3) function.'
1889 if link_check environ 'environ(3)' << \!
1890 #include <stdio.h> /* For C89 NULL */
1892 extern char **environ;
1894 return environ[0] == NULL;
1900 msg 'ERROR: we require the environ(3) array for subprocess control.'
1904 if link_check setenv '(un)?setenv(3)' '#define mx_HAVE_SETENV' << \!
1907 setenv("s-mailx
", "i want to see it cute
!", 1);
1908 unsetenv("s-mailx
");
1914 elif link_check setenv 'putenv(3)' '#define mx_HAVE_PUTENV' << \!
1917 putenv("s-mailx
=i want to see it cute
!");
1924 msg 'ERROR: we require either the setenv(3) or putenv(3) functions.'
1928 if link_check termios 'termios.h and tc*(3) family' << \!
1929 #include <termios.h>
1931 struct termios tios;
1934 tcgetattr(0, &tios);
1935 tcsetattr(0, TCSANOW | TCSADRAIN | TCSAFLUSH, &tios);
1936 ospeed = ((tcgetattr(0, &tios) == -1) ? B9600 : cfgetospeed(&tios));
1943 msg 'ERROR: we require termios.h and the tc[gs]etattr() function family.'
1944 msg 'That much Unix we indulge ourselves.'
1950 if link_check vsnprintf 'vsnprintf(3)' << \!
1953 static void dome(char *buf, size_t blen, ...){
1957 vsnprintf(buf, blen, "%s
", ap);
1963 dome(b, sizeof b, "string
");
1970 feat_bail_required ERRORS
1973 if [ "${have_vsnprintf}" = yes ]; then
1975 link_check va_copy "va_copy
(3) (as
${2})" \
1976 "#define mx_HAVE_N_VA_COPY
1977 #define n_va_copy ${2}" <<_EOT
1981 # if defined __va_copy && !defined va_copy
1982 # define va_copy __va_copy
1985 static void dome2
(char
*buf
, size_t blen
, va_list src
){
1989 vsnprintf
(buf
, blen
, "%s", ap
);
1992 static void dome
(char
*buf
, size_t blen
, ...
){
1996 dome2
(buf
, blen
, ap
);
2002 dome
(b
, sizeof b
, "string");
2007 __va_copy
0 va_copy || __va_copy
1 __va_copy
2010 run_check pathconf
'f?pathconf(2)' '#define mx_HAVE_PATHCONF' << \
!
2017 rv |
= !(pathconf
(".", _PC_NAME_MAX
) >= 0 || errno
== 0 || errno
!= ENOSYS
);
2019 rv |
= !(pathconf
(".", _PC_PATH_MAX
) >= 0 || errno
== 0 || errno
!= ENOSYS
);
2021 /* Only link check
*/
2022 fpathconf
(0, _PC_NAME_MAX
);
2028 run_check pipe2
'pipe2(2)' '#define mx_HAVE_PIPE2' << \
!
2035 if(!pipe2
(fds
, O_CLOEXEC
) || errno
!= ENOSYS
)
2041 link_check tcgetwinsize
'tcgetwinsize(3)' '#define mx_HAVE_TCGETWINSIZE' << \
!
2042 #include <termios.h>
2046 tcgetwinsize
(0, &ws
);
2051 # We use this only then for now (need NOW+1)
2052 run_check utimensat
'utimensat(2)' '#define mx_HAVE_UTIMENSAT' << \
!
2053 #include <fcntl.h> /* For AT_* */
2054 #include <sys/stat.h>
2057 struct timespec ts
[2];
2059 ts
[0].tv_nsec
= UTIME_NOW
;
2060 ts
[1].tv_nsec
= UTIME_OMIT
;
2061 if(!utimensat
(AT_FDCWD
, "", ts
, 0) || errno
!= ENOSYS
)
2069 link_check putc_unlocked
'putc_unlocked(3)' \
2070 '#define mx_HAVE_PUTC_UNLOCKED' <<\
!
2073 putc_unlocked
('@', stdout
);
2078 link_check fchdir
'fchdir(3)' '#define mx_HAVE_FCHDIR' << \
!
2086 if link_check realpath
'realpath(3)' '#define mx_HAVE_REALPATH' << \
!
2089 char x_buf
[4096], *x
= realpath
(".", x_buf
);
2091 return (x
!= NULL
) ?
0 : 1;
2095 if run_check realpath_malloc
'realpath(3) takes NULL' \
2096 '#define mx_HAVE_REALPATH_NULL' << \
!
2099 char
*x
= realpath
(".", NULL
);
2103 return (x
!= NULL
) ?
0 : 1;
2111 link_check tm_gmtoff
'struct tm::tm_gmtoff' '#define mx_HAVE_TM_GMTOFF' << \
!
2117 return gmtime
(&t
)->tm_gmtoff
!= 0;
2122 ## optional and selectable
2125 if feat_yes DOTLOCK
; then
2126 if run_check readlink
'readlink(2)' << \
!
2132 if(!readlink
("here", buf
, sizeof buf
) || errno
!= ENOSYS
)
2140 feat_bail_required DOTLOCK
2144 if feat_yes DOTLOCK
; then
2145 if run_check fchown
'fchown(2)' << \
!
2149 if(!fchown
(0, 0, 0) || errno
!= ENOSYS
)
2157 feat_bail_required DOTLOCK
2161 if feat_yes DOTLOCK
; then
2162 if run_check prctl_dumpable
'prctl(2) + PR_SET_DUMPABLE' \
2163 '#define mx_HAVE_PRCTL_DUMPABLE' << \
!
2164 #include <sys/prctl.h>
2167 if(!prctl
(PR_SET_DUMPABLE
, 0) || errno
!= ENOSYS
)
2174 elif run_check procctl_trace_ctl
'procctl(2) + PROC_TRACE_CTL_DISABLE' \
2175 '#define mx_HAVE_PROCCTL_TRACE_CTL' << \
!
2176 #include <sys/procctl.h>
2180 int disable_trace
= PROC_TRACE_CTL_DISABLE
;
2181 if(procctl
(P_PID
, getpid
(), PROC_TRACE_CTL
, &disable_trace
) != -1 ||
2189 elif run_check prtrace_deny
'ptrace(2) + PT_DENY_ATTACH' \
2190 '#define mx_HAVE_PTRACE_DENY' << \
!
2191 #include <sys/ptrace.h>
2194 if(ptrace
(PT_DENY_ATTACH
, 0, 0, 0) != -1 || errno
!= ENOSYS
)
2201 elif run_check setpflags_protect
'setpflags(2) + __PROC_PROTECT' \
2202 '#define mx_HAVE_SETPFLAGS_PROTECT' << \
!
2206 if(!setpflags
(__PROC_PROTECT
, 1) || errno
!= ENOSYS
)
2216 ### FORK AWAY SHARED BASE SERIES ###
2218 BASE_CFLAGS
=${CFLAGS}
2219 BASE_INCS
=`squeeze_ws "${INCS}"`
2220 BASE_LDFLAGS
=${LDFLAGS}
2221 BASE_LIBS
=`squeeze_ws "${LIBS}"`
2223 ## The remains are expected to be used only by the main MUA binary!
2224 ## (And possibly by test programs)
2227 link_check setlocale
'setlocale(3)' '#define mx_HAVE_SETLOCALE' << \
!
2230 setlocale
(LC_ALL
, "");
2234 [ -n "${have_setlocale}" ] && OPT_LOCALES
=1
2236 OPT_MULTIBYTE_CHARSETS
=0
2238 OPT_TERMINAL_CHARSET
=0
2239 if [ -n "${have_setlocale}" ]; then
2240 link_check c90amend1
'ISO/IEC 9899:1990/Amendment 1:1995' \
2241 '#define mx_HAVE_C90AMEND1' << \
!
2247 char mbb
[MB_LEN_MAX
+ 1];
2252 mbtowc
(&wc, "x", 1);
2253 mbrtowc
(&wc, "x", 1, NULL
);
2255 return (mblen
("\0", 1) == 0);
2258 [ -n "${have_c90amend1}" ] && OPT_MULTIBYTE_CHARSETS
=1
2260 if [ -n "${have_c90amend1}" ]; then
2261 link_check wcwidth
'wcwidth(3)' '#define mx_HAVE_WCWIDTH' << \
!
2268 [ -n "${have_wcwidth}" ] && OPT_WIDE_GLYPHS
=1
2271 link_check nl_langinfo
'nl_langinfo(3)' '#define mx_HAVE_NL_LANGINFO' << \
!
2272 #include <langinfo.h>
2276 return (nl_langinfo
(CODESET
) == NULL
);
2279 [ -n "${have_nl_langinfo}" ] && OPT_TERMINAL_CHARSET
=1
2282 link_check fnmatch
'fnmatch(3)' '#define mx_HAVE_FNMATCH' << \
!
2283 #include <fnmatch.h>
2285 return (fnmatch
("*", ".", FNM_PATHNAME | FNM_PERIOD
) == FNM_NOMATCH
);
2289 link_check dirent_d_type
'struct dirent.d_type' \
2290 '#define mx_HAVE_DIRENT_TYPE' << \
!
2294 return !(de.d_type
== DT_UNKNOWN ||
2295 de.d_type
== DT_DIR || de.d_type
== DT_LNK
);
2300 ## optional and selectable
2303 # OPT_ICONV, VAL_ICONV {{{
2304 if feat_yes ICONV
; then
2305 if val_allof VAL_ICONV libc
,iconv; then
2308 msg
'ERROR: VAL_ICONV with invalid entries: %s' "${VAL_ICONV}"
2312 # To be able to create tests we need to figure out which replacement
2313 # sequence the iconv(3) implementation creates
2314 ${cat} > ${tmp2}.c
<< \
!
2315 #include <stdio.h> /* For C89 NULL */
2319 char inb
[16], oub
[16], *inbp
, *oubp
;
2325 memcpy
(inbp
= inb
, "\342\200\223", sizeof
("\342\200\223"));
2326 inl
= sizeof
("\342\200\223") -1;
2331 if((id
= iconv_open
("us-ascii", "utf-8")) == (iconv_t
)-1)
2335 if(iconv(id
, &inbp
, &inl
, &oubp
, &oul
) == (size_t
)-1)
2339 oul
= (size_t
)(oubp
- oub
);
2342 /* Character-wise replacement?
*/
2354 /* Byte-wise replacement?
*/
2355 if(oul
== sizeof
("\342\200\223") -1){
2357 if(!memcmp
(oub
, "???????", sizeof
("\342\200\223") -1))
2360 if(!memcmp
(oub
, "*******", sizeof
("\342\200\223") -1))
2366 if(id
!= (iconv_t
)-1)
2374 < ${tmp2}.c link_check
iconv 'iconv(3)' \
2375 '#define mx_HAVE_ICONV'
2376 [ $?
-eq 0 ] && return 0
2377 < ${tmp2}.c link_check
iconv 'iconv(3), GNU libiconv redirect aware' \
2378 '#define mx_HAVE_ICONV' '' '-DLIBICONV_PLUG'
2382 < ${tmp2}.c link_check
iconv 'iconv(3) functionality (via -liconv)' \
2383 '#define mx_HAVE_ICONV' '-liconv'
2387 feat_bail_required ICONV
2392 VAL_ICONV
="${VAL_ICONV},bye"
2397 eval val_iconv_
$randfun && break
2400 if feat_yes ICONV
&& feat_no CROSS_BUILD
; then
2401 { ${tmp}; } >/dev
/null
2>&1
2404 msg
'WARN: disabling ICONV due to faulty conversion/restrictions'
2405 feat_bail_required ICONV
2407 2) echo 'MAILX_ICONV_MODE=2;export MAILX_ICONV_MODE;' >> ${env};;
2408 3) echo 'MAILX_ICONV_MODE=3;export MAILX_ICONV_MODE;' >> ${env};;
2409 12) echo 'MAILX_ICONV_MODE=12;export MAILX_ICONV_MODE;' >> ${env};;
2410 13) echo 'MAILX_ICONV_MODE=13;export MAILX_ICONV_MODE;' >> ${env};;
2411 *) msg
'WARN: will restrict iconv(3) tests due to unknown replacement';;
2415 feat_is_disabled ICONV
2417 # }}} OPT_ICONV, VAL_ICONV
2419 if feat_yes NET
; then
2420 ${cat} > ${tmp2}.c
<< \
!
2421 #include <sys/types.h>
2422 #include <sys/socket.h>
2426 struct sockaddr_un soun
;
2428 if(socket
(AF_UNIX
, SOCK_STREAM
, 0) == -1 && errno
== ENOSYS
)
2430 if(connect
(0, (struct sockaddr
*)&soun
, 0) == -1 && errno
== ENOSYS
)
2432 if(shutdown
(0, SHUT_RD | SHUT_WR | SHUT_RDWR
) == -1 && errno
== ENOSYS
)
2438 < ${tmp2}.c run_check af_unix
'AF_UNIX sockets' \
2439 '#define mx_HAVE_UNIX_SOCKETS' ||
2440 < ${tmp2}.c run_check af_unix
'AF_UNIX sockets (via -lnsl)' \
2441 '#define mx_HAVE_UNIX_SOCKETS' '-lnsl' ||
2442 < ${tmp2}.c run_check af_unix
'AF_UNIX sockets (via -lsocket -lnsl)' \
2443 '#define mx_HAVE_UNIX_SOCKETS' '-lsocket -lnsl'
2446 if feat_yes NET
; then
2447 ${cat} > ${tmp2}.c
<< \
!
2448 #include <sys/types.h>
2449 #include <sys/socket.h>
2450 #include <netinet/in.h>
2455 if(socket
(AF_INET
, SOCK_STREAM
, 0) == -1 && errno
== ENOSYS
)
2457 if(connect
(0, &s
, 0) == -1 && errno
== ENOSYS
)
2463 < ${tmp2}.c run_check sockets
'sockets' \
2464 '#define mx_HAVE_NET' ||
2465 < ${tmp2}.c run_check sockets
'sockets (via -lnsl)' \
2466 '#define mx_HAVE_NET' '-lnsl' ||
2467 < ${tmp2}.c run_check sockets
'sockets (via -lsocket -lnsl)' \
2468 '#define mx_HAVE_NET' '-lsocket -lnsl' ||
2469 feat_bail_required NET
2471 feat_is_disabled NET
2475 link_check sockopt
'[gs]etsockopt(2)' '#define mx_HAVE_SOCKOPT' << \
!
2476 #include <sys/socket.h>
2481 int sockfd
= 3, soe
;
2484 if(getsockopt
(sockfd
, SOL_SOCKET
, SO_ERROR
, &soe
, &sol
) == -1 &&
2487 if(setsockopt
(sockfd
, SOL_SOCKET
, SO_KEEPALIVE
, NULL
, 0) == -1 &&
2495 link_check nonblocksock
'non-blocking sockets' \
2496 '#define mx_HAVE_NONBLOCKSOCK' << \
!
2497 #include <sys/types.h>
2498 #include <sys/select.h>
2499 #include <sys/socket.h>
2500 #include <sys/time.h>
2501 #include <arpa/inet.h>
2502 #include <netinet/in.h>
2505 #include <string.h> /* FD_ZERO() SunOS 5.9, at least */
2511 struct sockaddr_in sin
;
2515 if((sofd
= socket
(AF_INET
, SOCK_STREAM
, 0)) == -1 && errno
== ENOSYS
)
2517 if(fcntl
(sofd
, F_SETFL
, O_NONBLOCK
) != 0)
2520 sin.sin_family
= AF_INET
;
2521 sin.sin_addr.s_addr
= inet_addr
("127.0.0.1");
2522 sin.sin_port
= htons
(80);
2523 if(connect
(sofd
, &sin
, sizeof sin
) == -1 && errno
== ENOSYS
)
2527 FD_SET
(sofd
, &fdset
);
2530 if((soe
= select(sofd
+ 1, NULL
, &fdset
, NULL
, &tv
)) == 1){
2532 getsockopt
(sofd
, SOL_SOCKET
, SO_ERROR
, &soe
, &sol
);
2535 }else if(soe
== -1 && errno
== ENOSYS
)
2543 if feat_yes NET
; then
2544 link_check getaddrinfo
'getaddrinfo(3)' \
2545 '#define mx_HAVE_GETADDRINFO' << \
!
2546 #include <sys/types.h>
2547 #include <sys/socket.h>
2551 struct addrinfo a
, *ap
;
2554 switch
((lrv
= getaddrinfo
("foo", "0", &a
, &ap
))){
2558 fprintf
(stderr
, "%s\n", gai_strerror
(lrv
));
2567 if feat_yes NET
&& [ -z "${have_getaddrinfo}" ]; then
2568 compile_check arpa_inet_h
'<arpa/inet.h>' \
2569 '#define mx_HAVE_ARPA_INET_H' << \
!
2570 #include <sys/types.h>
2571 #include <sys/socket.h>
2573 #include <netinet/in.h>
2574 #include <arpa/inet.h>
2577 ${cat} > ${tmp2}.c
<< \
!
2578 #include <sys/types.h>
2579 #include <sys/socket.h>
2583 #include <netinet/in.h>
2584 #ifdef mx_HAVE_ARPA_INET_H
2585 #include <arpa/inet.h>
2588 struct sockaddr_in servaddr
;
2589 unsigned short portno
;
2592 struct in_addr
**pptr
;
2595 if((ep
= getservbyname
("POPPY-PORT", "tcp")) != NULL
)
2596 portno
= (unsigned short
)ep-
>s_port
;
2598 if((hp
= gethostbyname
("POPPY-HOST")) != NULL
){
2599 pptr
= (struct in_addr
**)hp-
>h_addr_list
;
2600 if(hp-
>h_addrtype
!= AF_INET
)
2601 fprintf
(stderr
, "au\n");
2604 case HOST_NOT_FOUND
:
2610 fprintf
(stderr
, "au\n");
2615 memset
(&servaddr
, 0, sizeof servaddr
);
2616 servaddr.sin_family
= AF_INET
;
2617 servaddr.sin_port
= htons
(portno
);
2618 memcpy
(&servaddr.sin_addr
, *pptr
, sizeof
(struct in_addr
));
2619 fprintf
(stderr
, "Would connect to %s:%d ...\n",
2620 inet_ntoa
(**pptr
), (int
)portno
);
2625 < ${tmp2}.c link_check gethostbyname
'get(serv|host)byname(3)' ||
2626 < ${tmp2}.c link_check gethostbyname \
2627 'get(serv|host)byname(3) (via -nsl)' '' '-lnsl' ||
2628 < ${tmp2}.c link_check gethostbyname \
2629 'get(serv|host)byname(3) (via -lsocket -nsl)' \
2630 '' '-lsocket -lnsl' ||
2631 feat_bail_required NET
2634 feat_yes NET
&& [ -n "${have_sockopt}" ] &&
2635 link_check so_xtimeo
'SO_{RCV,SND}TIMEO' '#define mx_HAVE_SO_XTIMEO' << \
!
2636 #include <sys/socket.h>
2644 setsockopt
(sockfd
, SOL_SOCKET
, SO_SNDTIMEO
, &tv
, sizeof tv
);
2645 setsockopt
(sockfd
, SOL_SOCKET
, SO_RCVTIMEO
, &tv
, sizeof tv
);
2650 feat_yes NET
&& [ -n "${have_sockopt}" ] &&
2651 link_check so_linger
'SO_LINGER' '#define mx_HAVE_SO_LINGER' << \
!
2652 #include <sys/socket.h>
2660 setsockopt
(sockfd
, SOL_SOCKET
, SO_LINGER
, &li
, sizeof li
);
2666 if feat_yes TLS
; then # {{{
2667 # {{{ LibreSSL decided to define OPENSSL_VERSION_NUMBER with a useless value
2668 # instead of keeping it at the one that corresponds to the OpenSSL at fork
2669 # time: we need to test it first in order to get things right
2670 if compile_check _xtls
'TLS (LibreSSL)' \
2671 '#define mx_HAVE_TLS mx_TLS_IMPL_RESSL
2672 #define mx_HAVE_XTLS 0 /* 0 for LibreSSL */' << \
!
2673 #include <openssl/opensslv.h>
2674 #ifdef LIBRESSL_VERSION_NUMBER
2682 VAL_TLS_FEATURES
=libressl
,-tls-rand-file
2683 # TODO BORINGSSL, generalize this mess!
2684 elif compile_check _xtls
'TLS (OpenSSL >= v3.0.0)' \
2685 '#define mx_HAVE_TLS mx_TLS_IMPL_OPENSSL
2686 #define mx_HAVE_XTLS 0x30000' << \
!
2687 #include <openssl/opensslv.h>
2688 #if OPENSSL_VERSION_NUMBER + 0 >= 0x30000000L
2696 VAL_TLS_FEATURES
=libssl-0x30000
,-tls-rand-file
2697 elif compile_check _xtls
'TLS (OpenSSL >= v1.1.1)' \
2698 '#define mx_HAVE_TLS mx_TLS_IMPL_OPENSSL
2699 #define mx_HAVE_XTLS 0x10101' << \
!
2700 #include <openssl/opensslv.h>
2701 #if OPENSSL_VERSION_NUMBER + 0 >= 0x1010100fL
2709 VAL_TLS_FEATURES
=libssl-0x10100
,-tls-rand-file
2710 elif compile_check _xtls
'TLS (OpenSSL >= v1.1.0)' \
2711 '#define mx_HAVE_TLS mx_TLS_IMPL_OPENSSL
2712 #define mx_HAVE_XTLS 0x10100
2713 #define mx_XTLS_HAVE_RAND_FILE' << \
!
2714 #include <openssl/opensslv.h>
2715 #if OPENSSL_VERSION_NUMBER + 0 >= 0x10100000L
2723 VAL_TLS_FEATURES
=libssl-0x10100
,+tls-rand-file
2724 elif compile_check _xtls
'TLS (OpenSSL)' \
2725 '#define mx_HAVE_TLS mx_TLS_IMPL_OPENSSL
2726 #define mx_HAVE_XTLS 0x10000
2727 #define mx_XTLS_HAVE_RAND_FILE' << \
!
2728 #include <openssl/opensslv.h>
2729 #ifdef OPENSSL_VERSION_NUMBER
2737 VAL_TLS_FEATURES
=libssl-0x10000
,+tls-rand-file
2739 feat_bail_required TLS
2742 if feat_yes TLS
; then # {{{
2743 if [ -n "${ossl_v1_1}" ]; then
2744 without_check
1 xtls
'TLS new style TLS_client_method(3ssl)' \
2745 '#define mx_XTLS_CLIENT_METHOD TLS_client_method' \
2747 elif link_check xtls
'TLS new style TLS_client_method(3ssl)' \
2748 '#define mx_XTLS_CLIENT_METHOD TLS_client_method' \
2749 '-lssl -lcrypto' << \
!
2750 #include <openssl/ssl.h>
2751 #include <openssl/err.h>
2752 #include <openssl/x509v3.h>
2753 #include <openssl/x509.h>
2754 #include <openssl/rand.h>
2756 SSL_CTX
*ctx
= SSL_CTX_new
(TLS_client_method
());
2759 PEM_read_PrivateKey
(0, 0, 0, 0);
2765 elif link_check xtls
'TLS old style SSLv23_client_method(3ssl)' \
2766 '#define mx_XTLS_CLIENT_METHOD SSLv23_client_method' \
2767 '-lssl -lcrypto' << \
!
2768 #include <openssl/ssl.h>
2769 #include <openssl/err.h>
2770 #include <openssl/x509v3.h>
2771 #include <openssl/x509.h>
2772 #include <openssl/rand.h>
2774 SSL_CTX
*ctx
= SSL_CTX_new
(SSLv23_client_method
());
2777 PEM_read_PrivateKey
(0, 0, 0, 0);
2784 feat_bail_required TLS
2788 if feat_yes TLS
; then # {{{
2789 if [ -n "${ossl_v1_1}" ]; then
2790 without_check
1 xtls_stack_of
'*SSL STACK_OF()' \
2791 '#define mx_XTLS_HAVE_STACK_OF'
2792 elif compile_check xtls_stack_of
'*SSL STACK_OF()' \
2793 '#define mx_XTLS_HAVE_STACK_OF' << \
!
2794 #include <stdio.h> /* For C89 NULL */
2795 #include <openssl/ssl.h>
2796 #include <openssl/err.h>
2797 #include <openssl/x509v3.h>
2798 #include <openssl/x509.h>
2799 #include <openssl/rand.h>
2801 STACK_OF
(GENERAL_NAME
) *gens
= NULL
;
2803 printf("%p", gens
); /* to use it
*/
2811 if [ -n "${ossl_v1_1}" ]; then
2812 without_check
1 xtls_conf
'TLS OpenSSL_modules_load_file(3ssl)' \
2813 '#define mx_XTLS_HAVE_CONFIG'
2814 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+modules-load-file"
2815 elif link_check xtls_conf \
2816 'TLS OpenSSL_modules_load_file(3ssl) support' \
2817 '#define mx_XTLS_HAVE_CONFIG' << \
!
2818 #include <stdio.h> /* For C89 NULL */
2819 #include <openssl/conf.h>
2821 CONF_modules_load_file
(NULL
, NULL
, CONF_MFLAGS_IGNORE_MISSING_FILE
);
2822 #if mx_HAVE_XTLS < 0x10100
2823 CONF_modules_free
();
2829 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+modules-load-file"
2831 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},-modules-load-file"
2834 if [ -n "${ossl_v1_1}" ]; then
2835 without_check
1 xtls_conf_ctx
'TLS SSL_CONF_CTX support' \
2836 '#define mx_XTLS_HAVE_CONF_CTX'
2837 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+conf-ctx"
2838 elif link_check xtls_conf_ctx
'TLS SSL_CONF_CTX support' \
2839 '#define mx_XTLS_HAVE_CONF_CTX' << \
!
2840 #include <openssl/ssl.h>
2841 #include <openssl/err.h>
2843 SSL_CTX
*ctx
= SSL_CTX_new
(mx_XTLS_CLIENT_METHOD
());
2844 SSL_CONF_CTX
*cctx
= SSL_CONF_CTX_new
();
2846 SSL_CONF_CTX_set_flags
(cctx
,
2847 SSL_CONF_FLAG_FILE | SSL_CONF_FLAG_CLIENT |
2848 SSL_CONF_FLAG_CERTIFICATE | SSL_CONF_FLAG_SHOW_ERRORS
);
2849 SSL_CONF_CTX_set_ssl_ctx
(cctx
, ctx
);
2850 SSL_CONF_cmd
(cctx
, "Protocol", "ALL");
2851 SSL_CONF_CTX_finish
(cctx
);
2852 SSL_CONF_CTX_free
(cctx
);
2858 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+conf-ctx"
2860 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},-conf-ctx"
2863 if [ -n "${ossl_v1_1}" ]; then
2864 without_check
1 xtls_ctx_config
'TLS SSL_CTX_config(3ssl)' \
2865 '#define mx_XTLS_HAVE_CTX_CONFIG'
2866 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+ctx-config"
2867 elif [ -n "${have_xtls_conf}" ] && [ -n "${have_xtls_conf_ctx}" ] &&
2868 link_check xtls_ctx_config
'TLS SSL_CTX_config(3ssl)' \
2869 '#define mx_XTLS_HAVE_CTX_CONFIG' << \
!
2870 #include <stdio.h> /* For C89 NULL */
2871 #include <openssl/ssl.h>
2873 SSL_CTX_config
(NULL
, "SOMEVAL");
2878 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+ctx-config"
2880 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},-ctx-config"
2883 if [ -n "${ossl_v1_1}" ] && [ -n "${have_xtls_conf_ctx}" ]; then
2884 without_check
1 xtls_set_maxmin_proto \
2885 'TLS SSL_CTX_set_min_proto_version(3ssl)' \
2886 '#define mx_XTLS_HAVE_SET_MIN_PROTO_VERSION'
2887 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+ctx-set-maxmin-proto"
2888 elif link_check xtls_set_maxmin_proto \
2889 'TLS SSL_CTX_set_min_proto_version(3ssl)' \
2890 '#define mx_XTLS_HAVE_SET_MIN_PROTO_VERSION' << \
!
2891 #include <stdio.h> /* For C89 NULL */
2892 #include <openssl/ssl.h>
2894 SSL_CTX_set_min_proto_version
(NULL
, 0);
2895 SSL_CTX_set_max_proto_version
(NULL
, 10);
2900 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+ctx-set-maxmin-proto"
2902 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},-ctx-set-maxmin-proto"
2905 if [ -n "${ossl_v1_1}" ] && [ -n "${have_xtls_conf_ctx}" ]; then
2906 without_check
1 xtls_set_ciphersuites \
2907 'TLSv1.3 SSL_CTX_set_ciphersuites(3ssl)' \
2908 '#define mx_XTLS_HAVE_SET_CIPHERSUITES'
2909 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+ctx-set-ciphersuites"
2910 elif link_check xtls_set_ciphersuites \
2911 'TLSv1.3 SSL_CTX_set_ciphersuites(3ssl)' \
2912 '#define mx_XTLS_HAVE_SET_CIPHERSUITES' << \
!
2913 #include <stdio.h> /* For C89 NULL */
2914 #include <openssl/ssl.h>
2916 SSL_CTX_set_ciphersuites
(NULL
, NULL
);
2921 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},+ctx-set-ciphersuites"
2923 VAL_TLS_FEATURES
="${VAL_TLS_FEATURES},-ctx-set-ciphersuites"
2925 fi # feat_yes TLS }}}
2927 if feat_yes TLS
; then # digest etc algorithms {{{
2928 if feat_yes TLS_ALL_ALGORITHMS
; then
2929 if [ -n "${ossl_v1_1}" ]; then
2930 without_check
1 tls_all_algo
'TLS_ALL_ALGORITHMS support' \
2931 '#define mx_HAVE_TLS_ALL_ALGORITHMS'
2932 elif link_check tls_all_algo
'TLS all-algorithms support' \
2933 '#define mx_HAVE_TLS_ALL_ALGORITHMS' << \
!
2934 #include <openssl/evp.h>
2936 OpenSSL_add_all_algorithms
();
2937 EVP_get_cipherbyname
("two cents i never exist");
2938 #if mx_HAVE_XTLS < 0x10100
2947 feat_bail_required TLS_ALL_ALGORITHMS
2949 elif [ -n "${ossl_v1_1}" ]; then
2950 without_check
1 tls_all_algo \
2951 'TLS all-algorithms (always available in v1.1.0+)' \
2952 '#define mx_HAVE_TLS_ALL_ALGORITHMS'
2956 link_check tls_blake2
'TLS: BLAKE2 digests' \
2957 '#define mx_XTLS_HAVE_BLAKE2' << \
!
2958 #include <openssl/evp.h>
2967 link_check tls_sha3
'TLS: SHA-3 digests' \
2968 '#define mx_XTLS_HAVE_SHA3' << \
!
2969 #include <openssl/evp.h>
2979 if feat_yes MD5
&& feat_no NOEXTMD5
; then
2980 run_check tls_md5
'TLS: MD5 digest' '#define mx_XTLS_HAVE_MD5' << \
!
2983 #include <openssl/md5.h>
2985 char const dat
[] = "abrakadabrafidibus";
2986 char
dig[16], hex
[16 * 2];
2990 memset
(dig, 0, sizeof
(dig));
2991 memset
(hex
, 0, sizeof
(hex
));
2993 MD5_Update
(&ctx
, dat
, sizeof
(dat
) - 1);
2994 MD5_Final
(dig, &ctx
);
2996 #define su_cs_is_xdigit(n) ((n) > 9 ? (n) - 10 + 'a' : (n) + '0')
2997 for(i
= 0; i
< sizeof
(hex
) / 2; i
++){
2999 hex[j] = su_cs_is_xdigit((dig[i] & 0xf0) >> 4);
3000 hex[++j] = su_cs_is_xdigit(dig[i] & 0x0f);
3002 return !!memcmp("6d7d0a3d949da2e96f2aa010f65d8326", hex, sizeof(hex));
3007 feat_bail_required TLS_ALL_ALGORITHMS # feat_is_disabled?
3010 feat_is_disabled TLS
3011 feat_is_disabled TLS_ALL_ALGORITHMS
3012 fi # }}} feat_yes TLS
3013 printf '#ifdef mx_SOURCE\n' >> ${h}
3014 printf '#define VAL_TLS_FEATURES ",'"${VAL_TLS_FEATURES}"',"\n' >> ${h}
3015 printf '#endif /* mx_SOURCE */\n' >> ${h}
3017 if [ "${have_xtls}" = yes ]; then
3024 if val_allof VAL_RANDOM \
3025 "arc4,tls,libgetrandom,sysgetrandom,getentropy,urandom,builtin,error"; \
3029 msg
'ERROR: VAL_RANDOM with invalid entries: %s' "${VAL_RANDOM}"
3033 # Random implementations which completely replace our builtin machine
3036 link_check arc4random
'VAL_RANDOM: arc4random(3)' \
3037 '#define mx_HAVE_RANDOM mx_RANDOM_IMPL_ARC4' << \
!
3047 if feat_yes TLS
; then
3048 msg
' . VAL_RANDOM: tls ... yes'
3049 echo '#define mx_HAVE_RANDOM mx_RANDOM_IMPL_TLS' >> ${h}
3050 # Avoid reseeding, all we need is a streamy random producer
3051 link_check xtls_rand_drbg_set_reseed_defaults \
3052 'RAND_DRBG_set_reseed_defaults(3ssl)' \
3053 '#define mx_XTLS_HAVE_SET_RESEED_DEFAULTS' << \
!
3054 #include <openssl/rand_drbg.h>
3056 return (RAND_DRBG_set_reseed_defaults
(0, 0, 0, 0) != 0);
3061 msg
' . VAL_RANDOM: tls ... no'
3066 # The remaining random implementation are only used to seed our builtin
3067 # machine; we are prepared to handle failures of those, meaning that we have
3068 # a homebrew seeder; that tries to yield the time slice once, via
3069 # sched_yield(2) if available, nanosleep({0,0},) otherwise
3070 val__random_yield_ok
=
3071 val__random_check_yield
() {
3072 [ -n "${val__random_yield_ok}" ] && return
3073 val__random_yield_ok
=1
3074 link_check sched_yield
'sched_yield(2)' '#define mx_HAVE_SCHED_YIELD' << \
!
3083 val_random_libgetrandom
() {
3084 val__random_check_yield
3085 link_check getrandom
'VAL_RANDOM: getrandom(3) (in sys/random.h)' \
3086 '#define mx_HAVE_RANDOM mx_RANDOM_IMPL_GETRANDOM
3087 #define mx_RANDOM_GETRANDOM_FUN(B,S) getrandom(B, S, 0)
3088 #define mx_RANDOM_GETRANDOM_H <sys/random.h>' <<\
!
3089 #include <sys/random.h>
3092 getrandom
(buf
, sizeof buf
, 0);
3098 val_random_sysgetrandom
() {
3099 val__random_check_yield
3100 link_check getrandom
'VAL_RANDOM: getrandom(2) (via syscall(2))' \
3101 '#define mx_HAVE_RANDOM mx_RANDOM_IMPL_GETRANDOM
3102 #define mx_RANDOM_GETRANDOM_FUN(B,S) syscall(SYS_getrandom, B, S, 0)
3103 #define mx_RANDOM_GETRANDOM_H <sys/syscall.h>' <<\
!
3104 #include <sys/syscall.h>
3107 syscall
(SYS_getrandom
, buf
, sizeof buf
, 0);
3113 val_random_getentropy
() {
3114 val__random_check_yield
3115 link_check getentropy
'VAL_RANDOM: getentropy(3)' \
3116 '#define mx_HAVE_RANDOM mx_RANDOM_IMPL_GETENTROPY' <<\
!
3120 # ifndef GETENTROPY_MAX
3121 # define GETENTROPY_MAX 256
3124 typedef char cta
[GETENTROPY_MAX
>= 256 ?
1 : -1];
3125 char buf
[GETENTROPY_MAX
];
3127 if(!getentropy
(buf
, sizeof buf
) || errno
!= ENOSYS
)
3134 val_random_urandom
() {
3135 val__random_check_yield
3136 msg_nonl
' . VAL_RANDOM: /dev/urandom ... '
3137 if feat_yes CROSS_BUILD
; then
3138 msg
'yes (unchecked)'
3139 echo '#define mx_HAVE_RANDOM mx_RANDOM_IMPL_URANDOM' >> ${h}
3140 elif [ -f /dev
/urandom
]; then
3142 echo '#define mx_HAVE_RANDOM mx_RANDOM_IMPL_URANDOM' >> ${h}
3150 val_random_builtin
() {
3151 val__random_check_yield
3152 msg_nonl
' . VAL_RANDOM: builtin ... '
3153 if [ -n "${have_no_subsecond_time}" ]; then
3154 msg
'no\nERROR: %s %s' 'without a specialized PRG ' \
3155 'one of clock_gettime(2) and gettimeofday(2) is required.'
3159 echo '#define mx_HAVE_RANDOM mx_RANDOM_IMPL_BUILTIN' >> ${h}
3163 val_random_error
() {
3164 msg
'ERROR: VAL_RANDOM search reached "error" entry'
3170 VAL_RANDOM
="${VAL_RANDOM},error"
3171 set -- ${VAL_RANDOM}
3175 eval val_random_
$randfun && break
3179 if feat_yes GSSAPI
; then # {{{
3180 ${cat} > ${tmp2}.c
<< \
!
3181 #include <gssapi/gssapi.h>
3183 gss_import_name
(0, 0, GSS_C_NT_HOSTBASED_SERVICE
, 0);
3184 gss_init_sec_context
(0,0,0,0,0,0,0,0,0,0,0,0,0);
3188 ${sed} -e '1s/gssapi\///' < ${tmp2}.c > ${tmp3}.c
3190 if acmd_set i krb5-config
; then
3191 GSS_LIBS
="`CFLAGS= ${i} --libs gssapi`"
3192 GSS_INCS
="`CFLAGS= ${i} --cflags`"
3193 i
='GSS-API via krb5-config(1)'
3197 i
='GSS-API in gssapi/gssapi.h, libgssapi'
3199 if < ${tmp2}.c link_check gss \
3200 "${i}" '#define mx_HAVE_GSSAPI' "${GSS_LIBS}" "${GSS_INCS}" ||\
3201 < ${tmp3}.c link_check gss \
3202 'GSS-API in gssapi.h, libgssapi' \
3203 '#define mx_HAVE_GSSAPI
3204 #define GSSAPI_REG_INCLUDE' \
3206 < ${tmp2}.c link_check gss
'GSS-API in libgssapi_krb5' \
3207 '#define mx_HAVE_GSSAPI' \
3209 < ${tmp3}.c link_check gss \
3210 'GSS-API in libgssapi, OpenBSD-style (pre 5.3)' \
3211 '#define mx_HAVE_GSSAPI
3212 #define GSS_REG_INCLUDE' \
3213 '-lgssapi -lkrb5 -lcrypto' \
3214 '-I/usr/include/kerberosV' ||\
3215 < ${tmp2}.c link_check gss
'GSS-API in libgss' \
3216 '#define mx_HAVE_GSSAPI' \
3218 link_check gss
'GSS-API in libgssapi_krb5, old-style' \
3219 '#define mx_HAVE_GSSAPI
3220 #define GSSAPI_OLD_STYLE' \
3221 '-lgssapi_krb5' << \
!
3222 #include <gssapi/gssapi.h>
3223 #include <gssapi/gssapi_generic.h>
3225 gss_import_name
(0, 0, gss_nt_service_name
, 0);
3226 gss_init_sec_context
(0,0,0,0,0,0,0,0,0,0,0,0,0);
3233 feat_bail_required GSSAPI
3236 feat_is_disabled GSSAPI
3237 fi # feat_yes GSSAPI }}}
3239 if feat_yes IDNA
; then # {{{
3240 if val_allof VAL_IDNA
"idnkit,idn2,idn"; then
3243 msg
'ERROR: VAL_IDNA with invalid entries: %s' "${VAL_IDNA}"
3248 link_check idna
'OPT_IDNA->VAL_IDNA: GNU Libidn2' \
3249 '#define mx_HAVE_IDNA n_IDNA_IMPL_LIBIDN2' '-lidn2' << \
!
3252 char
*idna_utf8
, *idna_lc
;
3254 if(idn2_to_ascii_8z
("does.this.work", &idna_utf8
,
3255 IDN2_NONTRANSITIONAL | IDN2_TRANSITIONAL
) != IDN2_OK
)
3257 if(idn2_to_unicode_8zlz
(idna_utf8
, &idna_lc
, 0) != IDN2_OK
)
3260 idn2_free
(idna_utf8
);
3267 link_check idna
'OPT_IDNA->VAL_IDNA: GNU Libidn' \
3268 '#define mx_HAVE_IDNA n_IDNA_IMPL_LIBIDN' '-lidn' << \
!
3270 #include <idn-free.h>
3271 #include <stringprep.h> /* XXX we actually use our own iconv instead */
3273 char
*utf8
, *idna_ascii
, *idna_utf8
;
3275 utf8
= stringprep_locale_to_utf8
("does.this.work");
3276 if (idna_to_ascii_8z
(utf8
, &idna_ascii
, IDNA_USE_STD3_ASCII_RULES
)
3279 idn_free
(idna_ascii
);
3280 /* (Rather link check only here
) */
3281 idna_utf8
= stringprep_convert
(idna_ascii
, "UTF-8", "de_DE");
3288 link_check idna
'OPT_IDNA->VAL_IDNA: idnkit' \
3289 '#define mx_HAVE_IDNA n_IDNA_IMPL_IDNKIT' '-lidnkit' << \
!
3291 #include <idn/api.h>
3292 #include <idn/result.h>
3296 char local_name
[256];
3298 r
= idn_encodename
(IDN_ENCODE_APP
, "does.this.work", ace_name
,
3300 if (r
!= idn_success
) {
3301 fprintf
(stderr
, "idn_encodename failed: %s\n", idn_result_tostring
(r
));
3304 r
= idn_decodename
(IDN_DECODE_APP
, ace_name
, local_name
,sizeof
(local_name
));
3305 if (r
!= idn_success
) {
3306 fprintf
(stderr
, "idn_decodename failed: %s\n", idn_result_tostring
(r
));
3315 feat_bail_required IDNA
3320 VAL_IDNA
="${VAL_IDNA},bye"
3325 eval val_idna_
$randfun && break
3328 feat_is_disabled IDNA
3331 if feat_yes REGEX
; then
3332 if link_check regex
'regular expressions' '#define mx_HAVE_REGEX' << \
!
3340 status
= regcomp
(&re
, ".*bsd", REG_EXTENDED | REG_ICASE | REG_NOSUB
);
3341 xret
= regerror
(status
, &re
, NULL
, 0);
3342 status
= regexec
(&re
, "plan9", 0,NULL
, 0);
3344 return !(status
== REG_NOMATCH
);
3350 feat_bail_required REGEX
3353 feat_is_disabled REGEX
3356 if feat_yes MLE
; then
3357 if [ -n "${have_c90amend1}" ]; then
3359 echo '#define mx_HAVE_MLE' >> ${h}
3361 feat_bail_required MLE
3364 feat_is_disabled MLE
3367 if feat_yes HISTORY
; then
3368 if [ -n "${have_mle}" ]; then
3369 echo '#define mx_HAVE_HISTORY' >> ${h}
3371 feat_is_unsupported HISTORY
3374 feat_is_disabled HISTORY
3377 if feat_yes KEY_BINDINGS
; then
3378 if [ -n "${have_mle}" ]; then
3379 echo '#define mx_HAVE_KEY_BINDINGS' >> ${h}
3381 feat_is_unsupported KEY_BINDINGS
3384 feat_is_disabled KEY_BINDINGS
3387 if feat_yes TERMCAP
; then # {{{
3390 link_check termcap
"termcap(5) (via ${4}${ADDINC})" \
3391 "#define mx_HAVE_TERMCAP${3}" "${1}" "${ADDINC}" << _EOT
3396 #define UNCONST(P) ((void*)(unsigned long)(void const*)(P))
3397 static int my_putc(int c){return putchar(c);}
3399 char buf[1024+512], cmdbuf[2048], *cpb, *r1;
3400 int r2 = OK, r3 = ERR;
3402 tgetent(buf, getenv("TERM"));
3404 r1 = tgetstr(UNCONST("cm"), &cpb);
3406 r2 = tgetnum(UNCONST("Co"));
3407 r3 = tgetflag(UNCONST("ut"));
3408 tputs("cr", 1, &my_putc);
3409 return (r1 == NULL || r2 == -1 || r3 == 0);
3415 link_check terminfo
"terminfo(5) (via ${2}${ADDINC})" \
3416 '#define mx_HAVE_TERMCAP
3417 #define mx_HAVE_TERMCAP_CURSES
3418 #define mx_HAVE_TERMINFO' "${1}" "${ADDINC}" << _EOT
3422 #define UNCONST(P) ((void*)(unsigned long)(void const*)(P))
3423 static int my_putc(int c){return putchar(c);}
3429 r0 = setupterm(NULL, 1, &er);
3430 r1 = tigetflag(UNCONST("bce"));
3431 r2 = tigetnum(UNCONST("colors"));
3432 r3 = tigetstr(UNCONST("cr"));
3433 tp = tparm(r3, NULL, NULL, 0,0,0,0,0,0,0);
3434 tputs(tp, 1, &my_putc);
3435 return (r0 == ERR || r1 == -1 || r2 == -2 || r2 == -1 ||
3436 r3 == (char*)-1 || r3 == NULL);
3441 if feat_yes TERMCAP_VIA_TERMINFO
; then
3445 __terminfolib
-ltinfo -ltinfo ||
3446 __terminfolib
-lcurses -lcurses ||
3447 __terminfolib
-lcursesw -lcursesw ||
3451 if [ -n "${xbail}" ] && [ -d /usr
/local
/include
/ncurses
]; then
3452 ADDINC
=' -I/usr/local/include/ncurses'
3455 if [ -n "${xbail}" ] && [ -d /usr
/include
/ncurses
]; then
3456 ADDINC
=' -I/usr/include/ncurses'
3459 [ -n "${xbail}" ] && feat_bail_required TERMCAP_VIA_TERMINFO
3462 if [ -z "${have_terminfo}" ]; then
3466 __termcaplib
-ltermcap '' '' '-ltermcap' ||
3467 __termcaplib
-ltermcap '#include <curses.h>' '
3468 #define mx_HAVE_TERMCAP_CURSES' \
3469 'curses.h / -ltermcap' ||
3470 __termcaplib
-lcurses '#include <curses.h>' '
3471 #define mx_HAVE_TERMCAP_CURSES' \
3472 'curses.h / -lcurses' ||
3473 __termcaplib
-lcursesw '#include <curses.h>' '
3474 #define mx_HAVE_TERMCAP_CURSES' \
3475 'curses.h / -lcursesw' ||
3479 if [ -n "${xbail}" ] && [ -d /usr
/local
/include
/ncurses
]; then
3480 ADDINC
=' -I/usr/local/include/ncurses'
3483 if [ -n "${xbail}" ] && [ -d /usr
/include
/ncurses
]; then
3484 ADDINC
=' -I/usr/include/ncurses'
3487 [ -n "${xbail}" ] && feat_bail_required TERMCAP
3489 if [ -n "${have_termcap}" ]; then
3490 run_check tgetent_null \
3491 "tgetent(3) of termcap(5) takes NULL buffer" \
3492 "#define mx_HAVE_TGETENT_NULL_BUF" << _EOT
3493 #include <stdio.h> /* For C89 NULL */
3495 #ifdef mx_HAVE_TERMCAP_CURSES
3496 # include <curses.h>
3500 tgetent(NULL, getenv("TERM"));
3508 feat_is_disabled TERMCAP
3509 feat_is_disabled TERMCAP_VIA_TERMINFO
3513 ## Final feat_def's XXX should be loop over OPTIONs
3516 feat_def ALWAYS_UNICODE_LOCALE
3517 feat_def AMALGAMATION
0
3518 if feat_def CMD_CSOP
; then
3519 feat_def CMD_VEXPR
# v15compat: VEXPR needs CSOP for byte string ops YET
3521 feat_bail_required CMD_VEXPR
3524 feat_def CROSS_BUILD
3526 feat_def FILTER_HTML_TAGSOUP
3527 if feat_yes FILTER_QUOTE_FOLD
; then
3528 if [ -n "${have_c90amend1}" ] && [ -n "${have_wcwidth}" ]; then
3529 echo '#define mx_HAVE_FILTER_QUOTE_FOLD' >> ${h}
3531 feat_bail_required FILTER_QUOTE_FOLD
3534 feat_is_disabled FILTER_QUOTE_FOLD
3539 feat_def IMAP_SEARCH
3542 feat_def MD5
# XXX only sockets
3543 feat_def MTA_ALIASES
3548 feat_def SPAM_FILTER
3549 if feat_def SPAM_SPAMC
; then
3550 if acmd_set i spamc
; then
3551 echo "#define SPAM_SPAMC_PATH \"${i}\"" >> ${h}
3554 if feat_yes SPAM_SPAMC || feat_yes SPAM_FILTER
; then
3555 echo '#define mx_HAVE_SPAM' >> ${h}
3557 echo '/* mx_HAVE_SPAM */' >> ${h}
3562 feat_def ASAN_ADDRESS
0
3563 feat_def ASAN_MEMORY
0
3573 INCS
=`squeeze_ws "${INCS}"`
3574 LIBS
=`squeeze_ws "${LIBS}"`
3578 MX_LDFLAGS
=${LDFLAGS}
3580 SU_CFLAGS
=${BASE_CFLAGS}
3582 SU_INCS
=${BASE_INCS}
3583 SU_LDFLAGS
=${BASE_LDFLAGS}
3584 SU_LIBS
=${BASE_LIBS}
3585 PS_DOTLOCK_CFLAGS
=${BASE_CFLAGS}
3586 PS_DOTLOCK_INCS
=${BASE_INCS}
3587 PS_DOTLOCK_LDFLAGS
=${BASE_LDFLAGS}
3588 PS_DOTLOCK_LIBS
=${BASE_LIBS}
3592 MX_CFLAGS MX_INCS MX_LDFLAGS MX_LIBS \
3593 PS_DOTLOCK_CFLAGS PS_DOTLOCK_INCS PS_DOTLOCK_LDFLAGS PS_DOTLOCK_LIBS \
3594 SU_CFLAGS SU_CXXFLAGS SU_INCS SU_LDFLAGS SU_LIBS \
3597 printf -- "${i} = ${j}\n" >> ${mk}
3602 # mk-config.h (which becomes mx/gen-config.h)
3604 printf '#ifndef mx_GEN_CONFIG_H\n# define mx_GEN_CONFIG_H 1\n' > ${h}
3605 ${cat} ${tmp} >> ${h}
3606 printf '\n#ifdef mx_SOURCE\n' >> ${h}
3608 # Also need these for correct "second stage configuration changed
" detection */
3610 if (${CC} --version) >/dev/null 2>&1; then
3611 i=`${CC} --version 2>&1 | ${awk} '
3613 {if(length($0)) {if(l) l = l "\\\\n
"; l = l "@
" $0}}
3614 END{gsub(/"/, "", l
); print
"\\\\n" l
}
3616 elif (${CC} -v) >/dev/null 2>&1; then
3617 i=`${CC} -v 2>&1 | ${awk} '
3619 {if(length
($0)) {if(l
) l
= l
"\\\\n"; l
= l
"@" $0}}
3620 END
{gsub
(/"/, "", l); print "\\\\n
" l}
3624 CC=`squeeze_ws "${CC}"`
3625 CFLAGS=`squeeze_ws "${CFLAGS}"`
3626 LDLAGS=`squeeze_ws "${LDFLAGS}"`
3627 LIBS=`squeeze_ws "${LIBS}"`
3628 # $MAKEFLAGS often contain job-related things which hinders reproduceability.
3629 # For at least GNU make(1) we can separate those and our regular configuration
3630 # options by searching for the -- terminator
3631 COMMLINE=`printf '%s\n' "${COMMLINE}" | ${sed} -e 's/.*--\(.*\)/\1/'`
3632 COMMLINE=`squeeze_ws "${COMMLINE}"`
3634 i=`printf '%s %s %s\n' "${CC}" "${CFLAGS}" "${i}"`
3635 printf '#define VAL_BUILD_CC "%s
"\n' "$i" >> ${h}
3636 i=`string_to_char_array "${i}"`
3637 printf '#define VAL_BUILD_CC_ARRAY %s\n' "$i" >> ${h}
3638 i=`printf '%s %s %s\n' "${CC}" "${LDFLAGS}" "${LIBS}"`
3639 printf '#define VAL_BUILD_LD "%s
"\n' "$i" >> ${h}
3640 i=`string_to_char_array "${i}"`
3641 printf '#define VAL_BUILD_LD_ARRAY %s\n' "$i" >> ${h}
3643 printf '#define VAL_BUILD_REST "%s
"\n' "$i" >> ${h}
3644 i=`string_to_char_array "${i}"`
3645 printf '#define VAL_BUILD_REST_ARRAY %s\n' "$i" >> ${h}
3647 # Throw away all temporaries
3648 ${rm} -rf ${tmp0}.* ${tmp0}*
3650 # Create the string that is used by *features* and the version command.
3651 # Take this nice opportunity and generate a visual listing of included and
3652 # non-included features for the person who runs the configuration
3653 echo 'The following features are included (+) or not (-):' > ${tmp}
3654 set -- ${OPTIONS_DETECT} ${OPTIONS} ${OPTIONS_XTRA}
3655 printf '/* The "feature string
" */\n' >> ${h}
3656 # Prefix sth. to avoid that + is expanded by *folder* (echo $features)
3657 printf '#define VAL_FEATURES_CNT '${#}'\n#define VAL_FEATURES ",' >> ${h}
3661 sdoc=`option_doc_of ${opt}`
3662 [ -z "${sdoc}" ] && continue
3663 sopt="`echo ${opt} | ${tr} '[A-Z
]_
' '[a-z
]-'`"
3664 feat_yes ${opt} && sign=+ || sign=-
3665 printf -- "${sep}${sign}${sopt}" >> ${h}
3667 printf ' %s
%s
: %s
\n' ${sign} ${sopt} "${sdoc}" >> ${tmp}
3669 # TODO instead of using sh+tr+awk+printf, use awk, drop option_doc_of, inc here
3671 #${awk} -v opts="${OPTIONS_DETECT} ${OPTIONS} ${OPTIONS_XTRA}" \
3672 # -v xopts="${XOPTIONS_DETECT} ${XOPTIONS} ${XOPTIONS_XTRA}" \
3673 printf ',"\n' >> ${h}
3675 # Create the real mk-config.mk
3676 # Note we cannot use explicit ./ filename prefix for source and object
3677 # pathnames because of a bug in bmake(1)
3678 msg 'Creating object make rules'
3680 if feat_yes DOTLOCK; then
3681 printf "OPTIONAL_PS_DOTLOCK
= \$
(VAL_PS_DOTLOCK
)\n" >> ${mk}
3682 (cd "${SRCDIR}"; ${SHELL} ../mk/make-rules.sh ps-dotlock/*.c) >> ${mk}
3684 printf "OPTIONAL_PS_DOTLOCK =\n" >> ${mk}
3687 # Not those SU sources with su_USECASE_MX_DISABLED
3691 ${grep} su_USECASE_MX_DISABLED "${f}" >/dev/null >&1 && continue
3697 if feat_no AMALGAMATION
; then
3698 (cd "${SRCDIR}"; ${SHELL} ../mk/make-rules.sh ${su_sources}) >> ${mk}
3699 (cd "${SRCDIR}"; ${SHELL} ../mk/make-rules.sh mx/*.c) >> ${mk}
3700 mx_obj
='$(MX_C_OBJ)' su_obj
='$(SU_C_OBJ)'
3702 (cd "${SRCDIR}"; COUNT_MODE=0 ${SHELL} ../mk/make-rules.sh mx/*.c) >> ${mk}
3704 printf 'mx-main.o: gen-bltin-rc.h gen-mime-types.h' >> ${mk}
3706 printf '\n#endif /* mx_SOURCE */\n' >> ${h}
3707 printf '/* mx_HAVE_AMALGAMATION: include sources */\n' >> ${h}
3708 printf '#elif mx_GEN_CONFIG_H + 0 == 1\n' >> ${h}
3709 printf '# undef mx_GEN_CONFIG_H\n' >> ${h}
3710 printf '# define mx_GEN_CONFIG_H 2\n#ifdef mx_SOURCE\n' >> ${h}
3712 for i in `printf '%s\n' ${su_sources} | ${sort}`; do
3713 printf '# include "%s
%s
"\n' "${SRCDIR}" "${i}" >> ${h}
3717 for i
in `printf '%s\n' "${SRCDIR}"mx/*.c | ${sort}`; do
3719 if [ "${i}" = main.c
]; then
3722 printf '# include "%s%s"\n' "${SRCDIR}mx/" "${i}" >> ${h}
3726 printf 'OBJ = %s\n' "${mx_obj} ${su_obj}" >> "${mk}"
3728 printf '#endif /* mx_SOURCE */\n#endif /* mx_GEN_CONFIG_H */\n' >> ${h}
3731 ${cat} "${TOPDIR}"mk/make-config.in >> ${mk}
3737 # We have completed the new configuration header. Check whether *really*
3738 # Do the "second stage configuration changed
" detection, exit if nothing to do
3739 if [ -f ${oldh} ]; then
3740 if ${cmp} ${h} ${oldh} >/dev/null 2>&1; then
3741 ${mv} -f ${oldh} ${h}
3742 msg 'Effective configuration is up-to-date'
3747 msg 'Effective configuration has been updated..'
3750 if [ -n "${config_updated}" ]; then
3751 msg 'Wiping away old objects and such..'
3752 ( cd "${OBJDIR}"; oldmk=`${basename} ${oldmk}`; ${MAKE} -f ${oldmk} clean
)
3755 # Ensure user edits in mx-config.h are incorporated, and that our generated
3756 # mk-config.h becomes the new public mx/gen-config.h.
3757 ${cp} -f "${CWDDIR}"mx-config.h "${CWDDIR}"include/mx/config.h
3758 ${cp} -f ${h} "${CWDDIR}"include
/mx
/gen-config.h
3761 while read l
; do msg
"${l}"; done < ${tmp}
3764 msg
' . System-wide resource file: %s/%s' \
3765 "${VAL_SYSCONFDIR}" "${VAL_SYSCONFRC}"
3766 msg
' . bindir: %s' "${VAL_BINDIR}"
3767 if feat_yes DOTLOCK
; then
3768 msg
' . libexecdir: %s' "${VAL_LIBEXECDIR}"
3770 msg
' . mandir: %s' "${VAL_MANDIR}"
3771 msg
' . M(ail)T(ransfer)A(gent): %s (argv0: %s)' \
3772 "${VAL_MTA}" "${VAL_MTA_ARGV0}"
3773 msg
' . $MAIL spool directory: %s' "${VAL_MAIL}"
3774 if feat_yes MAILCAP
; then
3775 msg
' . Built-in $MAILCAPS path search: %s' "${VAL_MAILCAPS}"
3779 if [ -n "${have_fnmatch}" ] && [ -n "${have_fchdir}" ]; then
3783 if [ -z "${have_fnmatch}" ]; then
3784 msg
' . The function fnmatch(3) could not be found.'
3785 msg
' Filename patterns like wildcard are not supported on your system'
3787 if [ -z "${have_fchdir}" ]; then
3788 msg
' . The function fchdir(2) could not be found.'
3789 msg
' We will use chdir(2) instead.'
3790 msg
' This is a problem only if the current working directory is changed'
3791 msg
' while this program is inside of it'