Implement AI_CANONIDN.

This commit is contained in:
Ulrich Drepper 2004-03-13 06:53:42 +00:00
parent a17256a4fa
commit de079fee8c
2 changed files with 44 additions and 5 deletions

View File

@ -577,6 +577,7 @@ struct gaicb
# define AI_IDN 0x0040 /* IDN encode input (assuming it is encoded # define AI_IDN 0x0040 /* IDN encode input (assuming it is encoded
in the current locale's character set) in the current locale's character set)
before looking it up. */ before looking it up. */
# define AI_CANONIDN 0x0080 /* Translate canonical name from IDN format. */
# endif # endif
/* Error values for `getaddrinfo' function. */ /* Error values for `getaddrinfo' function. */

View File

@ -55,8 +55,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <nsswitch.h> #include <nsswitch.h>
#include <not-cancel.h> #include <not-cancel.h>
#ifdef HAVE_LIBIDN
extern int __idna_to_ascii_lz (const char *input, char **output, int flags); extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
#define IDNA_SUCCESS 0 extern int __idna_to_unicode_lzlz (const char *input, char **output,
int flags);
# include <libidn/idna.h>
#endif
#define GAIH_OKIFUNSPEC 0x0100 #define GAIH_OKIFUNSPEC 0x0100
#define GAIH_EAI ~(GAIH_OKIFUNSPEC) #define GAIH_EAI ~(GAIH_OKIFUNSPEC)
@ -548,9 +552,20 @@ gaih_inet (const char *name, const struct gaih_service *service,
char *p = NULL; char *p = NULL;
rc = __idna_to_ascii_lz (name, &p, 0); rc = __idna_to_ascii_lz (name, &p, 0);
if (rc != IDNA_SUCCESS) if (rc != IDNA_SUCCESS)
return -EAI_IDN_ENCODE; {
name = strdupa (p); if (rc == IDNA_MALLOC_ERROR)
free (p); return -EAI_MEMORY;
if (rc == IDNA_DLOPEN_ERROR)
return -EAI_SYSTEM;
return -EAI_IDN_ENCODE;
}
/* In case the output string is the same as the input string
no new string has been allocated. */
if (p != name)
{
name = strdupa (p);
free (p);
}
} }
#endif #endif
@ -820,6 +835,29 @@ gaih_inet (const char *name, const struct gaih_service *service,
if (c == NULL) if (c == NULL)
return GAIH_OKIFUNSPEC | -EAI_NONAME; return GAIH_OKIFUNSPEC | -EAI_NONAME;
#ifdef HAVE_LIBIDN
if (req->ai_flags & AI_CANONIDN)
{
char *out;
int rc = __idna_to_unicode_lzlz (c, &out, 0);
if (rc != IDNA_SUCCESS)
{
if (rc == IDNA_MALLOC_ERROR)
return -EAI_MEMORY;
if (rc == IDNA_DLOPEN_ERROR)
return -EAI_SYSTEM;
return -EAI_IDN_ENCODE;
}
/* In case the output string is the same as the input
string no new string has been allocated. */
if (out != c)
{
c = strdupa (out);
free (out);
}
}
#endif
namelen = strlen (c) + 1; namelen = strlen (c) + 1;
} }
else else
@ -1268,7 +1306,7 @@ getaddrinfo (const char *name, const char *service,
if (hints->ai_flags if (hints->ai_flags
& ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
#ifdef HAVE_LIBIDN #ifdef HAVE_LIBIDN
|AI_IDN |AI_IDN|AI_CANONIDN
#endif #endif
|AI_ALL)) |AI_ALL))
return EAI_BADFLAGS; return EAI_BADFLAGS;