From 33a2a872544f8111c846bcd34afd06dba4fd7421 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Sun, 18 Nov 2007 17:24:37 +0000 Subject: [PATCH] (socket_connection): Use getaddrinfo if available. --- lib-src/ChangeLog | 4 ++++ lib-src/pop.c | 56 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 98d73e73dd5..9a88a606449 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,7 @@ +2007-11-18 Jan Dj,Ad(Brv + + * pop.c (socket_connection): Use getaddrinfo if available. + 2007-11-15 Francesco Potort,Al(B * etags.c: Make prototypes for extern definitions, and add all diff --git a/lib-src/pop.c b/lib-src/pop.c index 9fcbe4b370c..df9e41f6457 100644 --- a/lib-src/pop.c +++ b/lib-src/pop.c @@ -1010,7 +1010,13 @@ socket_connection (host, flags) 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 @@ socket_connection (host, flags) #endif /* KERBEROS */ int try_count = 0; + int connect_ok; #ifdef WINDOWSNT { @@ -1097,6 +1104,41 @@ socket_connection (host, flags) } +#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 @@ socket_connection (host, flags) 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 @@ socket_connection (host, flags) } #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 @@ socket_connection (host, flags) 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 @@ socket_connection (host, flags) } } - 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 @@ socket_connection (host, flags) } #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 @@ socket_connection (host, flags) (struct sockaddr_in *) 0, "KPOPV0.1"); free ((char *) ticket); - free (realhost); if (rem != KSUCCESS) { strcpy (pop_error, KRB_ERROR); -- 2.39.2