Hi Lonnie!
On Wed, 31 Dec 2014 17:00:24 -0600, Lonnie Abelbeck wrote:
> msmtp: cannot locate host foo.example.com: Bad value for ai_flags
> msmtp: could not send mail...
>
> [...]
>
> So the bottom line seems to be that checking the headers for AI_IDN
> (via autoconf) is not good enough.
This is not good. I asked on the glibc-help mailing list if this is
really intended, and how one is supposed to check if AI_IDN actually
works.
In my opinion, AI_IDN should only be defined if it is actually
supported. Otherwise, you need to build with a fall back code path that
uses libidn, and if you need that anyway, then why bother with an
unreliable AI_IDN? There's nothing to gain, you just make the code less
readable.
> The question is can autoconf determine if glibc was build with
> libidn ?
I did not find a way, except for AC_RUN_IFELSE, which does not work
when cross-compiling.
> Another solution would be a --with-idn configure switch which would
> add a USE_IDN config.h define.
I suggest --enable-gai-idn. The --with-* switches are typically
used to include external libraries.
See the attached patch.
This also allows for future systems that simply support IDN without
having to use AI_IDN (although we then need a way for configure to
detect this). For example, musl plans to support IDN by default
http://wiki.musl-libc.org/wiki/Functional_differences_from_glibc#Name_Resolver_.2F_DNS).
I think they are right.
An unrelated question: why are you using glibc without IDN support?
Libidn is included in the glibc sources; I cannot see a reason to
disable it.
Regards,
Martin
diff --git a/configure.ac b/configure.ac
index 8205335..95fd2e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,33 +136,45 @@ if test "$libgsasl" != "no"; then
fi
AM_CONDITIONAL([HAVE_LIBGSASL], [test "$libgsasl" = "yes"])
-dnl Do we need libidn for IDN support? Modern systems don't.
-want_libidn=yes
-AC_CHECK_DECL([AI_IDN], [], [], [#include <netdb.h>])
-if test "$ac_cv_have_decl_AI_IDN" = "yes"; then
- if test "$have_tls" = "no"; then
- want_libidn=no
- elif test "$tls_lib" = "GnuTLS"; then
- gnutls_has_idn=no
- AC_MSG_CHECKING([if GnuTLS has builtin IDN support])
- CFLAGS_BAK="$CFLAGS"
- CFLAGS="$CFLAGS $tls_CFLAGS"
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM([[
- #include <gnutls/gnutls.h>
- #if GNUTLS_VERSION_NUMBER < 0x030400
- error: GnuTLS does not have builtin IDN support
- #endif]],
- [[int x = 0;]])],
- [gnutls_has_idn="yes"], [])
- CFLAGS="$CFLAGS_BAK"
- AC_MSG_RESULT([$gnutls_has_idn])
- if test "$gnutls_has_idn" = "yes"; then
- want_libidn=no
- fi
+dnl Check if getaddrinfo() has IDN support (and we want to use it)
+AC_ARG_ENABLE([gai-idn],
+ [AS_HELP_STRING([--enable-gai-idn], [Use IDN support from getaddrinfo if available. Enabled by default.])],
+ [if test "$enableval" = "yes"; then want_gai_idn="yes"; else want_gai_idn="no"; fi], [want_gai_idn="yes"])
+have_gai_idn=no
+if test "$want_gai_idn" = "yes"; then
+ AC_CHECK_DECL([AI_IDN], [], [], [#include <netdb.h>])
+ if test "$ac_cv_have_decl_AI_IDN" = "yes"; then
+ have_gai_idn=yes
+ AC_DEFINE([HAVE_GAI_IDN], [1], [Define to 1 if getaddrinfo supports IDN])
fi
fi
+
+dnl Check if TLS has IDN support
+have_tls_idn=no
+if test "$tls_lib" = "GnuTLS"; then
+ AC_MSG_CHECKING([if GnuTLS has builtin IDN support])
+ CFLAGS_BAK="$CFLAGS"
+ CFLAGS="$CFLAGS $tls_CFLAGS"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #include <gnutls/gnutls.h>
+ #if GNUTLS_VERSION_NUMBER < 0x030400
+ error: GnuTLS does not have builtin IDN support
+ #endif]],
+ [[int x = 0;]])],
+ [have_tls_idn="yes"], [])
+ CFLAGS="$CFLAGS_BAK"
+ AC_MSG_RESULT([$have_tls_idn])
+fi
+
+dnl Do we need libidn for IDN support? Modern systems don't.
AC_MSG_CHECKING([if libidn is needed for IDN support])
+want_libidn=no
+if test "$have_gai_idn" = "no"; then
+ want_libidn=yes
+elif test "$have_tls" = "yes" -a "$have_tls_idn" = "no"; then
+ want_libidn=yes
+fi
AC_MSG_RESULT([$want_libidn])
dnl GNU Libidn
diff --git a/src/net.c b/src/net.c
index eae0948..85644b9 100644
--- a/src/net.c
+++ b/src/net.c
@@ -620,8 +620,10 @@ int net_open_socket(
hints.ai_addr = NULL;
hints.ai_next = NULL;
port_string = xasprintf("%d", port);
-#ifdef AI_IDN
+#ifdef HAVE_GAI_IDN
+# ifdef AI_IDN
hints.ai_flags |= AI_IDN;
+# endif
#elif defined(HAVE_LIBIDN)
idna_to_ascii_lz(hostname, &idn_hostname, 0);
#endif
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
_______________________________________________
msmtp-users mailing list
msmtp-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/msmtp-users