Mercurial > emacs
changeset 86210:7ae58179773b
(socket_connection): Use getaddrinfo if available.
author | Jan Djärv <jan.h.d@swipnet.se> |
---|---|
date | Sun, 18 Nov 2007 17:24:27 +0000 |
parents | fc3e525371e2 |
children | 28ea5d5d04ca |
files | lib-src/pop.c |
diffstat | 1 files changed, 51 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/lib-src/pop.c Sun Nov 18 13:54:46 2007 +0000 +++ b/lib-src/pop.c Sun Nov 18 17:24:27 2007 +0000 @@ -1010,7 +1010,13 @@ char *host; int flags; { +#ifdef HAVE_GETADDRINFO + struct addrinfo *res, *it; + struct addrinfo hints; + int ret; +#else /* !HAVE_GETADDRINFO */ struct hostent *hostent; +#endif struct servent *servent; struct sockaddr_in addr; char found_port = 0; @@ -1036,6 +1042,7 @@ #endif /* KERBEROS */ int try_count = 0; + int connect_ok; #ifdef WINDOWSNT { @@ -1097,6 +1104,41 @@ } +#ifdef HAVE_GETADDRINFO + memset (&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_ADDRCONFIG; + hints.ai_family = AF_INET; + do + { + ret = getaddrinfo (host, service, &hints, &res); + try_count++; + if (ret != 0 && (ret != EAI_AGAIN || try_count == 5)) + { + strcpy (pop_error, "Could not determine POP server's address"); + return (-1); + } + } while (ret != 0); + + if (ret == 0) + { + it = res; + while (it) + { + if (it->ai_addrlen == sizeof (addr)) + { + struct sockaddr_in *in_a = (struct sockaddr_in *) it->ai_addr; + bcopy (&in_a->sin_addr, (char *) &addr.sin_addr, + sizeof (addr.sin_addr)); + if (! connect (sock, (struct sockaddr *) &addr, sizeof (addr))) + break; + } + it = it->ai_next; + } + connect_ok = it != NULL; + freeaddrinfo (res); + } +#else /* !HAVE_GETADDRINFO */ do { hostent = gethostbyname (host); @@ -1116,10 +1158,12 @@ break; hostent->h_addr_list++; } + connect_ok = *hostent->h_addr_list != NULL; +#endif /* !HAVE_GETADDRINFO */ #define CONNECT_ERROR "Could not connect to POP server: " - if (! *hostent->h_addr_list) + if (! connect_ok) { CLOSESOCKET (sock); strcpy (pop_error, CONNECT_ERROR); @@ -1130,6 +1174,10 @@ } #ifdef KERBEROS + + realhost = alloca (strlen (hostent->h_name) + 1); + strcpy (realhost, hostent->h_name); + #define KRB_ERROR "Kerberos error connecting to POP server: " if (! (flags & POP_NO_KERBEROS)) { @@ -1157,7 +1205,7 @@ if (rem = krb5_cc_get_principal (kcontext, ccdef, &client)) goto krb5error; - for (cp = hostent->h_name; *cp; cp++) + for (cp = realhost; *cp; cp++) { if (isupper (*cp)) { @@ -1165,7 +1213,7 @@ } } - if (rem = krb5_sname_to_principal (kcontext, hostent->h_name, + if (rem = krb5_sname_to_principal (kcontext, realhost, POP_SERVICE, FALSE, &server)) goto krb5error; @@ -1210,7 +1258,6 @@ } #else /* ! KERBEROS5 */ ticket = (KTEXT) malloc (sizeof (KTEXT_ST)); - realhost = strdup (hostent->h_name); rem = krb_sendauth (0L, sock, ticket, "pop", realhost, (char *) krb_realmofhost (realhost), (unsigned long) 0, &msg_data, &cred, schedule, @@ -1218,7 +1265,6 @@ (struct sockaddr_in *) 0, "KPOPV0.1"); free ((char *) ticket); - free (realhost); if (rem != KSUCCESS) { strcpy (pop_error, KRB_ERROR);