diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 0181db614a..482809ccf0 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -190,7 +190,8 @@ help(void) { " +[no]fail (Don't try next server on SERVFAIL)\n" " +[no]header-only (Send query without a question section)\n" " +[no]identify (ID responders in short answers)\n" -" +[no]idnout (convert IDN response)\n" +" +[no]idnin (Parse IDN names)\n" +" +[no]idnout (Convert IDN response)\n" " +[no]ignore (Don't revert to TCP for TC responses.)\n" " +[no]keepalive (Request EDNS TCP keepalive)\n" " +[no]keepopen (Keep the TCP socket open between queries)\n" @@ -1045,13 +1046,29 @@ plus_option(const char *option, isc_boolean_t is_batchfile, lookup->identify = state; break; case 'n': - FULLCHECK("idnout"); + switch (cmd[3]) { + case 'i': + FULLCHECK("idnin"); #ifndef WITH_IDN_SUPPORT - fprintf(stderr, ";; IDN support not enabled\n"); + fprintf(stderr, ";; IDN input support" + " not enabled\n"); #else - lookup->idnout = state; + lookup->idnin = state; #endif break; + case 'o': + FULLCHECK("idnout"); +#ifndef WITH_IDN_OUT_SUPPORT + fprintf(stderr, ";; IDN output support" + " not enabled\n"); +#else + lookup->idnout = state; +#endif + break; + default: + goto invalid_option; + } + break; default: goto invalid_option; } diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook index 219cfd5dee..80318bb32f 100644 --- a/bin/dig/dig.docbook +++ b/bin/dig/dig.docbook @@ -776,6 +776,17 @@ + + + + + Process [do not process] IDN domain names on input. + This requires IDN SUPPORT to have been enabled at + compile time. The default is to process IDN input. + + + + @@ -1288,10 +1299,9 @@ dig +qr www.isc.org any -x 127.0.0.1 isc.org ns +noqr dig appropriately converts character encoding of domain name before sending a request to DNS server or displaying a reply from the server. - If you'd like to turn off the IDN support for some reason, defines - the IDN_DISABLE environment variable. - The IDN support is disabled if the variable is set when - dig runs. + If you'd like to turn off the IDN support for some reason, use + parameters +noidnin and + +noidnout. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index d752d156a4..efa8b49e36 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -148,59 +148,31 @@ static char servercookie[256]; #ifdef WITH_IDN_SUPPORT static void idn_initialize(void); -static isc_result_t idn_locale_to_utf8(const char *from, - char *to, - size_t tolen); -static isc_result_t idn_utf8_to_ace(const char *from, +static isc_result_t idn_locale_to_ace(const char *from, char *to, size_t tolen); + +#ifdef WITH_IDNKIT +static isc_result_t idnkit_initialize(void); +#endif +#endif /* WITH_IDN_SUPPORT */ + +#ifdef WITH_IDN_OUT_SUPPORT static isc_result_t idn_ace_to_locale(const char *from, char *to, size_t tolen); static isc_result_t output_filter(isc_buffer_t *buffer, unsigned int used_org, isc_boolean_t absolute); -static isc_result_t append_textname(char *name, - const char *origin, - size_t namesize); - #define MAXDLEN 256 #ifdef WITH_IDNKIT -static isc_result_t idnkit_initialize(void); -static isc_result_t idnkit_locale_to_utf8(const char *from, - char *to, - size_t tolen); -static isc_result_t idnkit_utf8_to_ace(const char *from, - char *to, - size_t tolen); -static isc_result_t idnkit_ace_to_locale(const char *from, - char *to, - size_t tolen); - -#elif WITH_LIBIDN -static isc_result_t libidn_locale_to_utf8(const char *from, - char *to, - size_t tolen); -static isc_result_t libidn_utf8_to_ace(const char *from, - char *to, - size_t tolen); -static isc_result_t libidn_ace_to_locale(const char *from, - char *to, - size_t tolen); - -#elif WITH_LIBIDN2 -static isc_result_t libidn2_locale_to_utf8(const char *from, - char *to, - size_t tolen); -static isc_result_t libidn2_utf8_to_ace(const char *from, - char *to, - size_t tolen); -static isc_result_t libidn2_ace_to_locale(const char *from, - char *to, - size_t tolen); +int idnoptions = 0; #endif -#endif /* WITH_IDN_SUPPORT */ +static isc_result_t idn_ace_to_locale(const char *from, + char *to, + size_t tolen); +#endif /* WITH_IDN_OUT_SUPPORT */ isc_socket_t *keep = NULL; isc_sockaddr_t keepaddr; @@ -701,7 +673,12 @@ make_empty_lookup(void) { looknew->ttlunits = ISC_FALSE; looknew->ttlunits = ISC_FALSE; looknew->qr = ISC_FALSE; -#ifdef WITH_IDN +#ifdef WITH_IDN_SUPPORT + looknew->idnin = ISC_TRUE; +#else + looknew->idnin = ISC_FALSE; +#endif +#ifdef WITH_IDN_OUT_SUPPORT looknew->idnout = ISC_TRUE; #else looknew->idnout = ISC_FALSE; @@ -846,6 +823,7 @@ clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) { looknew->nocrypto = lookold->nocrypto; looknew->ttlunits = lookold->ttlunits; looknew->qr = lookold->qr; + looknew->idnin = lookold->idnin; looknew->idnout = lookold->idnout; looknew->udpsize = lookold->udpsize; looknew->edns = lookold->edns; @@ -1353,6 +1331,12 @@ setup_system(isc_boolean_t ipv4only, isc_boolean_t ipv6only) { idn_initialize(); #endif +#ifdef WITH_IDN_OUT_SUPPORT + /* Set domain name -> text post-conversion filter. */ + result = dns_name_settotextfilter(output_filter); + check_result(result, "dns_name_settotextfilter"); +#endif + if (keyfile[0] != 0) setup_file_key(); else if (keysecret[0] != 0) @@ -2081,11 +2065,13 @@ setup_lookup(dig_lookup_t *lookup) { char store[MXNAME]; char ecsbuf[20]; char cookiebuf[256]; + char *origin = NULL; + char *textname = NULL; #ifdef WITH_IDN_SUPPORT - char utf8_textname[MXNAME], utf8_origin[MXNAME], idn_textname[MXNAME]; + char idn_origin[MXNAME], idn_textname[MXNAME]; #endif -#ifdef WITH_IDN_SUPPORT +#ifdef WITH_IDN_OUT_SUPPORT result = dns_name_settotextfilter(lookup->idnout ? output_filter : NULL); check_result(result, "dns_name_settotextfilter"); @@ -2123,10 +2109,15 @@ setup_lookup(dig_lookup_t *lookup) { * `textname' doesn't contain TLD, but local mapping needs * TLD. */ + textname = lookup->textname; #ifdef WITH_IDN_SUPPORT - result = idn_locale_to_utf8(lookup->textname, utf8_textname, - sizeof(utf8_textname)); - check_result(result, "convert textname to UTF-8"); + if (lookup->idnin) { + result = idn_locale_to_ace(lookup->textname, idn_textname, + sizeof(idn_textname)); + check_result(result, "convert textname to IDN encoding"); + debug("idn_textname: %s", idn_textname); + textname = idn_textname; + } #endif /* @@ -2137,11 +2128,7 @@ setup_lookup(dig_lookup_t *lookup) { * is TRUE or we got a domain line in the resolv.conf file. */ if (lookup->new_search) { -#ifdef WITH_IDN_SUPPORT - if ((count_dots(utf8_textname) >= ndots) || !usesearch) -#else - if ((count_dots(lookup->textname) >= ndots) || !usesearch) -#endif + if ((count_dots(textname) >= ndots) || !usesearch) { lookup->origin = NULL; /* Force abs lookup */ lookup->done_as_is = ISC_TRUE; @@ -2152,26 +2139,6 @@ setup_lookup(dig_lookup_t *lookup) { } } -#ifdef WITH_IDN_SUPPORT - if (lookup->origin != NULL) { - debug("trying origin %s", lookup->origin->origin); - result = idn_locale_to_utf8(lookup->origin->origin, - utf8_origin, sizeof(utf8_origin)); - check_result(result, "convert origin to UTF-8"); - result = append_textname(utf8_textname, - utf8_origin, sizeof(utf8_textname)); - check_result(result, "append origin to textname"); - } - result = idn_utf8_to_ace(utf8_textname, - idn_textname, sizeof(idn_textname)); - if (lookup->origin != NULL && result == ISC_R_NOSPACE) { - dns_message_puttempname(lookup->sendmsg, - &lookup->name); - return ISC_FALSE; - } - check_result(result, "convert UTF-8 textname to IDN encoding"); - -#else /* WITH_IDN_SUPPORT */ if (lookup->origin != NULL) { debug("trying origin %s", lookup->origin->origin); result = dns_message_gettempname(lookup->sendmsg, @@ -2179,8 +2146,18 @@ setup_lookup(dig_lookup_t *lookup) { check_result(result, "dns_message_gettempname"); dns_name_init(lookup->oname, NULL); /* XXX Helper funct to conv char* to name? */ - len = (unsigned int) strlen(lookup->origin->origin); - isc_buffer_init(&b, lookup->origin->origin, len); + origin = lookup->origin->origin; +#ifdef WITH_IDN_SUPPORT + if (lookup->idnin) { + result = idn_locale_to_ace(lookup->origin->origin, + idn_origin, sizeof(idn_origin)); + check_result(result, "convert origin to IDN encoding"); + debug("trying idn origin %s", idn_origin); + origin = idn_origin; + } +#endif + len = (unsigned int) strlen(origin); + isc_buffer_init(&b, origin, len); isc_buffer_add(&b, len); result = dns_name_fromtext(lookup->oname, &b, dns_rootname, 0, &lookup->onamebuf); @@ -2190,7 +2167,7 @@ setup_lookup(dig_lookup_t *lookup) { dns_message_puttempname(lookup->sendmsg, &lookup->oname); fatal("'%s' is not in legal name syntax (%s)", - lookup->origin->origin, + origin, isc_result_totext(result)); } if (lookup->trace && lookup->trace_root) { @@ -2201,8 +2178,8 @@ setup_lookup(dig_lookup_t *lookup) { dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); - len = (unsigned int) strlen(lookup->textname); - isc_buffer_init(&b, lookup->textname, len); + len = (unsigned int) strlen(textname); + isc_buffer_init(&b, textname, len); isc_buffer_add(&b, len); result = dns_name_fromtext(name, &b, NULL, 0, NULL); if (result == ISC_R_SUCCESS && @@ -2227,20 +2204,13 @@ setup_lookup(dig_lookup_t *lookup) { } } dns_message_puttempname(lookup->sendmsg, &lookup->oname); - } else -#endif - { + } else { debug("using root origin"); if (lookup->trace && lookup->trace_root) dns_name_clone(dns_rootname, lookup->name); else { -#ifdef WITH_IDN_SUPPORT - len = (unsigned int) strlen(idn_textname); - isc_buffer_init(&b, idn_textname, len); -#else - len = (unsigned int) strlen(lookup->textname); - isc_buffer_init(&b, lookup->textname, len); -#endif + len = (unsigned int) strlen(textname); + isc_buffer_init(&b, textname, len); isc_buffer_add(&b, len); result = dns_name_fromtext(lookup->name, &b, dns_rootname, 0, @@ -4286,57 +4256,23 @@ destroy_libs(void) { #ifdef WITH_IDN_SUPPORT static void idn_initialize(void) { +#ifdef WITH_IDNKIT isc_result_t result; +#endif #ifdef HAVE_SETLOCALE /* Set locale */ (void)setlocale(LC_ALL, ""); #endif -#ifdef HAVE_IDNKIT +#ifdef WITH_IDNKIT /* Create configuration context. */ result = idnkit_initialize(); check_result(result, "idnkit initializationt"); #endif - - /* Set domain name -> text post-conversion filter. */ - result = dns_name_settotextfilter(output_filter); - check_result(result, "dns_name_settotextfilter"); -} - -static isc_result_t -idn_locale_to_utf8(const char *from, char *to, size_t tolen) { -#ifdef WITH_IDNKIT - return (idnkit_locale_to_utf8(from, to, tolen)); -#elif WITH_LIBIDN - return (libidn_locale_to_utf8(from, to, tolen)); -#else /* WITH_LIBIDN2 */ - return (libidn2_locale_to_utf8(from, to, tolen)); -#endif -} - -static isc_result_t -idn_utf8_to_ace(const char *from, char *to, size_t tolen) { -#ifdef WITH_IDNKIT - return (idnkit_utf8_to_ace(from, to, tolen)); -#elif WITH_LIBIDN - return (libidn_utf8_to_ace(from, to, tolen)); -#else /* WITH_LIBIDN2 */ - return (libidn2_utf8_to_ace(from, to, tolen)); -#endif -} - -static isc_result_t -idn_ace_to_locale(const char *from, char *to, size_t tolen) { -#ifdef WITH_IDNKIT - return (idnkit_ace_to_locale(from, to, tolen)); -#elif WITH_LIBIDN - return (libidn_ace_to_locale(from, to, tolen)); -#else /* WITH_LIBIDN2 */ - return (libidn2_ace_to_locale(from, to, tolen)); -#endif } +#ifdef WITH_IDN_OUT_SUPPORT static isc_result_t output_filter(isc_buffer_t *buffer, unsigned int used_org, isc_boolean_t absolute) @@ -4369,8 +4305,9 @@ output_filter(isc_buffer_t *buffer, unsigned int used_org, * Convert contents of 'tmp1' to local encoding. */ result = idn_ace_to_locale(tmp1, tmp2, sizeof(tmp2)); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (ISC_R_SUCCESS); + } strlcpy(tmp1, tmp2, MAXDLEN); /* @@ -4390,146 +4327,97 @@ output_filter(isc_buffer_t *buffer, unsigned int used_org, return (ISC_R_SUCCESS); } - -static isc_result_t -append_textname(char *name, const char *origin, size_t namesize) { - size_t namelen = strlen(name); - size_t originlen = strlen(origin); - - /* Already absolute? */ - if (namelen > 0 && name[namelen - 1] == '.') - return (ISC_R_SUCCESS); - - /* Append dot and origin */ - if (namelen + 1 + originlen >= namesize) { - debug("append_textname failure: name + origin is too long"); - return (ISC_R_NOSPACE); - } - - if (*origin != '.') - name[namelen++] = '.'; - (void)strlcpy(name + namelen, origin, namesize - namelen); - return (ISC_R_SUCCESS); -} +#endif #ifdef WITH_IDNKIT +static void +idnkit_check_result(idn_result_t result, const char *msg) { + if (result != idn_success) { + fatal("%s: %s", msg, idn_result_tostring(result)); + } +} + static isc_result_t idnkit_initialize(void) { idn_result_t result; result = idn_nameinit(1); - - if (result == idn_success) { - return (ISC_R_SUCCESS); - } else { - debug("idnkit api initialization failed: %s", - idn_result_tostring(result)); - return (ISC_R_FAILURE); - } + idnkit_check_result(result, "idnkit api initialization failed"); + return (ISC_R_SUCCESS); } static isc_result_t -idnkit_locale_to_utf8(const char *from, char *to, size_t tolen) { +idn_locale_to_ace(const char *from, char *to, size_t tolen) { + char utf8_textname[MXNAME]; idn_result_t result; - result = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, from, to, tolen); + result = idn_encodename(IDN_LOCALCONV | IDN_DELIMMAP, from, + utf8_textname, sizeof(utf8_textname)); + idnkit_check_result(result, "idnkit idn_encodename to utf8 failed"); - if (result == idn_success) { - return (ISC_R_SUCCESS); - } else { - debug("idnkit idn_encodename failed: %s", - idn_result_tostring(result)); - if (result == idn_invalid_length) - return (ISC_R_NOSPACE); - else - return (ISC_R_FAILURE); - } + result = idn_encodename(idnoptions | IDN_LOCALMAP | IDN_NAMEPREP | + IDN_IDNCONV | IDN_LENCHECK, + utf8_textname, to, tolen); + idnkit_check_result(result, "idnkit idn_encodename to idn failed"); + return (ISC_R_SUCCESS); } static isc_result_t -idnkit_utf8_to_ace(const char *from, char *to, size_t tolen) { - idn_result_t result; - - result = idn_encodename(IDN_LOCALMAP | IDN_NAMEPREP | - IDN_IDNCONV | IDN_LENCHECK, from, to, tolen); - - if (result == idn_success) { - return (ISC_R_SUCCESS); - } else { - debug("idnkit idn_encodename failed: %s", - idn_result_tostring(result)); - return (ISC_R_FAILURE); - } -} - -static isc_result_t -idnkit_ace_to_locale(const char *from, char *to, size_t tolen) { +idn_ace_to_locale(const char *from, char *to, size_t tolen) { idn_result_t result; result = idn_decodename(IDN_DECODE_APP, from, to, tolen); - - if (result == idn_success) { - return (ISC_R_SUCCESS); - } else { + if (result != idn_success) { debug("idnkit idn_decodename failed: %s", - idn_result_tostring(result) ); + idn_result_tostring(result)); return (ISC_R_FAILURE); } + return (ISC_R_SUCCESS); } #endif /* WITH_IDNKIT */ #ifdef WITH_LIBIDN static isc_result_t -libidn_locale_to_utf8(const char *from, char *to, size_t tolen) { +idn_locale_to_ace(const char *from, char *to, size_t tolen) { isc_result_t result = ISC_R_FAILURE; + int res; char *tmp_str = NULL; + char *ace_str = NULL; tmp_str = stringprep_locale_to_utf8(from); if (tmp_str != NULL) { if (strlen(tmp_str) >= tolen) { debug("UTF-8 string is too long"); - result = ISC_R_FAILURE; - goto cleanup; + free(tmp_str); + return ISC_R_NOSPACE; } - - (void) strncpy(to, tmp_str, tolen); - - result = ISC_R_SUCCESS; } + else + return ISC_R_FAILURE; -cleanup: - free(tmp_str); - return (result); -} - -static isc_result_t -libidn_utf8_to_ace(const char *from, char *to, size_t tolen) { - int res; - char *tmp_str = NULL; - - res = idna_to_ascii_8z(from, &tmp_str, 0); - + res = idna_to_ascii_8z(tmp_str, &ace_str, 0); if (res == IDNA_SUCCESS) { /* check the length */ if (strlen(tmp_str) >= tolen) { debug("encoded ASC string is too long"); - return ISC_R_FAILURE; + result = ISC_R_NOSPACE; + } else { + (void) strncpy(to, ace_str, tolen); + result = ISC_R_SUCCESS; } - - (void) strncpy(to, tmp_str, tolen); - free(tmp_str); - return ISC_R_SUCCESS; - } else { - debug("libidn idna_to_ascii_8z failed: %s", - idna_strerror(res)); } - return ISC_R_FAILURE; + free(tmp_str); + free(ace_str); + if (res != IDNA_SUCCESS) { + fatal("idna_to_ascii_8z failed: %s", idna_strerror(res)); + } + return (result); } static isc_result_t -libidn_ace_to_locale(const char *from, char *to, size_t tolen) { +idn_ace_to_locale(const char *from, char *to, size_t tolen) { int res; isc_result_t result; char *tmp_str = NULL; @@ -4548,7 +4436,7 @@ libidn_ace_to_locale(const char *from, char *to, size_t tolen) { result = ISC_R_SUCCESS; } else { - debug("libidn idna_to_unicode_8z8l failed: %s", + debug("idna_to_unicode_8z8l failed: %s", idna_strerror(res)); result = ISC_R_FAILURE; } @@ -4560,9 +4448,8 @@ cleanup: #endif /* WITH_LIBIDN */ #ifdef WITH_LIBIDN2 -/* Converts name from locale directly into ACE format, skip UTF-8 step */ static isc_result_t -libidn2_locale_to_utf8(const char *from, char *to, size_t tolen) { +idn_locale_to_ace(const char *from, char *to, size_t tolen) { int res; char *tmp_str = NULL; @@ -4574,40 +4461,22 @@ libidn2_locale_to_utf8(const char *from, char *to, size_t tolen) { /* check the length */ if (strlen(tmp_str) >= tolen) { debug("ACE string is too long"); - free(tmp_str); - return ISC_R_FAILURE; + idn2_free(tmp_str); + return ISC_R_NOSPACE; } - (void) strncpy(to, tmp_str, tolen); - free(tmp_str); - + (void) strlcpy(to, tmp_str, tolen); + idn2_free(tmp_str); return ISC_R_SUCCESS; } - debug("libidn2 idn2_lookup_u8 failed: %s", idn2_strerror(res)); + fatal("idn2_lookup_ul failed: %s", idn2_strerror(res)); return ISC_R_FAILURE; } +#ifdef WITH_IDN_OUT_SUPPORT static isc_result_t -libidn2_utf8_to_ace(const char *from, char *to, size_t tolen) { - int res; - - /* Just check the format again. */ - res = idn2_to_unicode_8zlz(from, NULL, - IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT); - if (res == IDN2_OK) { - strncpy(to, from, tolen); - return ISC_R_SUCCESS; - } - debug("libidn2 idn2_to_unicode_8zlz failed: %s", idn2_strerror(res)); - if (res == IDN2_TOO_BIG_DOMAIN) - return ISC_R_NOSPACE; - else - return ISC_R_FAILURE; -} - -static isc_result_t -libidn2_ace_to_locale(const char *from, char *to, size_t tolen) { +idn_ace_to_locale(const char *from, char *to, size_t tolen) { int res; char *tmp_str = NULL; @@ -4626,11 +4495,12 @@ libidn2_ace_to_locale(const char *from, char *to, size_t tolen) { free(tmp_str); return ISC_R_SUCCESS; } else { - debug("libidn idna_to_ascii_8z failed: %s", + debug("idn2_to_unicode_8zlz failed: %s", idn2_strerror(res)); } return ISC_R_FAILURE; } +#endif /* WITH_IDN_OUT_SUPPORT */ #endif /* WITH_LIBIDN2 */ #endif /* WITH_IDN_SUPPORT */ diff --git a/bin/dig/host.c b/bin/dig/host.c index 5aa242e105..cbb548d2fc 100644 --- a/bin/dig/host.c +++ b/bin/dig/host.c @@ -19,7 +19,7 @@ #include #endif -#ifdef WITH_IDN +#ifdef WITH_IDNKIT #include #include #include diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index 48fc8f14b5..b08e99f94b 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -129,6 +129,7 @@ struct dig_lookup { use_usec, nocrypto, ttlunits, + idnin, idnout, qr; char textname[MXNAME]; /*% Name we're going to be looking up */ @@ -268,7 +269,7 @@ extern char *progname; extern int tries; extern int fatalexit; extern isc_boolean_t verbose; -#ifdef WITH_IDN +#ifdef WITH_IDNKIT extern int idnoptions; #endif diff --git a/config.h.in b/config.h.in index 79eba6384e..757a1730db 100644 --- a/config.h.in +++ b/config.h.in @@ -599,6 +599,9 @@ int sigwait(const unsigned int *set, int *sig); /* define if idnkit support is to be included. */ #undef WITH_IDN +#undef WITH_IDN_OUT_SUPPORT + +/* define if IDN input support is to be included. */ /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD diff --git a/configure.in b/configure.in index 4c7b06b4b7..7962465151 100644 --- a/configure.in +++ b/configure.in @@ -4701,8 +4701,8 @@ NOM_PATH_FILE(XSLT_DBLATEX_FASTBOOK, xsl/latex_book_fast.xsl, $dblatex_xsl_trees # IDN support using idnkit # AC_ARG_WITH(idnkit, - AS_HELP_STRING([--with-idn[=PATH]], - [enable IDN support using idnkit idnkit yes|no|path]), + AS_HELP_STRING([--with-idnkit[=PATH]], + [enable IDN support using idnkit [yes|no|path]]), use_idnkit="$withval", use_idnkit="no") case "$use_idnkit" in yes) @@ -4776,8 +4776,9 @@ AC_SUBST(IDNKIT_LIBS) # # IDN support using libidn # +LIBIDN_LIBS= AC_ARG_WITH(libidn, - [ --with-libidn[=PATH] enable IDN support using GNU libidn yes|no|path], + AS_HELP_STRING([--with-libidn[=PATH]], [enable IDN support using GNU libidn [yes|no|path]]), use_libidn="$withval", use_libidn="no") case "$use_libidn" in yes) @@ -4786,19 +4787,19 @@ yes) else libidn_path=$prefix fi + LIBIDN_LIBS="-lidn" ;; no) ;; *) + LIBIDN_LIBS="-L$use_libidn/lib -lidn" libidn_path="$use_libidn" ;; esac -LIBIDN_LIBS= if test "$use_libidn" != no; then AC_DEFINE(WITH_LIBIDN, 1, [define if libidn support is to be included.]) STD_CINCLUDES="$STD_CINCLUDES -I$libidn_path/include" - LIBIDN_LIBS="-lidn" fi AC_SUBST(LIBIDN_LIBS) @@ -4806,8 +4807,9 @@ AC_SUBST(LIBIDN_LIBS) # IDN support using libidn2 # +LIBIDN2_LIBS= AC_ARG_WITH(libidn2, - [ --with-libidn2[=PATH] enable IDN support using GNU libidn2 yes|no|path], + AS_HELP_STRING([--with-libidn2[=PATH]], [enable IDN support using GNU libidn2 [yes|no|path]]), use_libidn2="$withval", use_libidn2="no") case "$use_libidn2" in yes) @@ -4816,19 +4818,36 @@ yes) else libidn2_path=$prefix fi + LIBIDN2_LIBS="-lidn2" ;; no) ;; *) libidn2_path="$use_libidn2" + LIBIDN2_LIBS="-L$libidn2_path/lib -lidn2" ;; esac -LIBIDN2_LIBS= if test "$use_libidn2" != no; then AC_DEFINE(WITH_LIBIDN2, 1, [define if libidn2 support is to be included.]) + saved_cflags="$CFLAGS" + saved_libs="$LIBS" + LIBS="$LIBIDN2_LIBS" + CFLAGS="-I$libidn2_path/include" + + AC_MSG_NOTICE(checking for idn2_to_unicode_8zlz) +AC_TRY_LINK([ +#include +],[ idn2_to_unicode_8zlz(".", NULL, IDN2_NONTRANSITIONAL|IDN2_NFC_INPUT); ], + [AC_MSG_RESULT(yes) + use_libidn2_out=yes], + [AC_MSG_RESULT(no) + use_libidn2_out=no] +) + STD_CINCLUDES="$STD_CINCLUDES -I$libidn2_path/include" - LIBIDN_LIBS="-lidn2" + LIBS="$saved_libs" + CFLAGS="$saved_cflags" fi AC_SUBST(LIBIDN2_LIBS) @@ -4849,7 +4868,10 @@ fi # the IDN support is on if test "$use_idnkit" != no || test "$use_libidn" != no || test "$use_libidn2" != no; then - AC_DEFINE(WITH_IDN_SUPPORT, 1, [define if IDN support is to be included.]) + AC_DEFINE(WITH_IDN_SUPPORT, 1, [define if IDN input support is to be included.]) + if test "$use_libidn2" = no || test "$use_libidn2_out" != no; then + AC_DEFINE(WITH_IDN_OUT_SUPPORT, 1, [define if IDN output support is to be included.]) + fi fi #