diff options
| author | Jan Djärv | 2007-11-18 17:24:37 +0000 |
|---|---|---|
| committer | Jan Djärv | 2007-11-18 17:24:37 +0000 |
| commit | 33a2a872544f8111c846bcd34afd06dba4fd7421 (patch) | |
| tree | 80991b0f360ac7c1bcfc867db6d7d8eb6bc898ee /lib-src | |
| parent | 95fbaefc5f16818e3c5fe53e4fd08a382d5d5345 (diff) | |
| download | emacs-33a2a872544f8111c846bcd34afd06dba4fd7421.tar.gz emacs-33a2a872544f8111c846bcd34afd06dba4fd7421.zip | |
(socket_connection): Use getaddrinfo if available.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/ChangeLog | 4 | ||||
| -rw-r--r-- | 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 @@ | |||
| 1 | 2007-11-18 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * pop.c (socket_connection): Use getaddrinfo if available. | ||
| 4 | |||
| 1 | 2007-11-15 Francesco Potort,Al(B <pot@gnu.org> | 5 | 2007-11-15 Francesco Potort,Al(B <pot@gnu.org> |
| 2 | 6 | ||
| 3 | * etags.c: Make prototypes for extern definitions, and add all | 7 | * 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) | |||
| 1010 | char *host; | 1010 | char *host; |
| 1011 | int flags; | 1011 | int flags; |
| 1012 | { | 1012 | { |
| 1013 | #ifdef HAVE_GETADDRINFO | ||
| 1014 | struct addrinfo *res, *it; | ||
| 1015 | struct addrinfo hints; | ||
| 1016 | int ret; | ||
| 1017 | #else /* !HAVE_GETADDRINFO */ | ||
| 1013 | struct hostent *hostent; | 1018 | struct hostent *hostent; |
| 1019 | #endif | ||
| 1014 | struct servent *servent; | 1020 | struct servent *servent; |
| 1015 | struct sockaddr_in addr; | 1021 | struct sockaddr_in addr; |
| 1016 | char found_port = 0; | 1022 | char found_port = 0; |
| @@ -1036,6 +1042,7 @@ socket_connection (host, flags) | |||
| 1036 | #endif /* KERBEROS */ | 1042 | #endif /* KERBEROS */ |
| 1037 | 1043 | ||
| 1038 | int try_count = 0; | 1044 | int try_count = 0; |
| 1045 | int connect_ok; | ||
| 1039 | 1046 | ||
| 1040 | #ifdef WINDOWSNT | 1047 | #ifdef WINDOWSNT |
| 1041 | { | 1048 | { |
| @@ -1097,6 +1104,41 @@ socket_connection (host, flags) | |||
| 1097 | 1104 | ||
| 1098 | } | 1105 | } |
| 1099 | 1106 | ||
| 1107 | #ifdef HAVE_GETADDRINFO | ||
| 1108 | memset (&hints, 0, sizeof(hints)); | ||
| 1109 | hints.ai_socktype = SOCK_STREAM; | ||
| 1110 | hints.ai_flags = AI_ADDRCONFIG; | ||
| 1111 | hints.ai_family = AF_INET; | ||
| 1112 | do | ||
| 1113 | { | ||
| 1114 | ret = getaddrinfo (host, service, &hints, &res); | ||
| 1115 | try_count++; | ||
| 1116 | if (ret != 0 && (ret != EAI_AGAIN || try_count == 5)) | ||
| 1117 | { | ||
| 1118 | strcpy (pop_error, "Could not determine POP server's address"); | ||
| 1119 | return (-1); | ||
| 1120 | } | ||
| 1121 | } while (ret != 0); | ||
| 1122 | |||
| 1123 | if (ret == 0) | ||
| 1124 | { | ||
| 1125 | it = res; | ||
| 1126 | while (it) | ||
| 1127 | { | ||
| 1128 | if (it->ai_addrlen == sizeof (addr)) | ||
| 1129 | { | ||
| 1130 | struct sockaddr_in *in_a = (struct sockaddr_in *) it->ai_addr; | ||
| 1131 | bcopy (&in_a->sin_addr, (char *) &addr.sin_addr, | ||
| 1132 | sizeof (addr.sin_addr)); | ||
| 1133 | if (! connect (sock, (struct sockaddr *) &addr, sizeof (addr))) | ||
| 1134 | break; | ||
| 1135 | } | ||
| 1136 | it = it->ai_next; | ||
| 1137 | } | ||
| 1138 | connect_ok = it != NULL; | ||
| 1139 | freeaddrinfo (res); | ||
| 1140 | } | ||
| 1141 | #else /* !HAVE_GETADDRINFO */ | ||
| 1100 | do | 1142 | do |
| 1101 | { | 1143 | { |
| 1102 | hostent = gethostbyname (host); | 1144 | hostent = gethostbyname (host); |
| @@ -1116,10 +1158,12 @@ socket_connection (host, flags) | |||
| 1116 | break; | 1158 | break; |
| 1117 | hostent->h_addr_list++; | 1159 | hostent->h_addr_list++; |
| 1118 | } | 1160 | } |
| 1161 | connect_ok = *hostent->h_addr_list != NULL; | ||
| 1162 | #endif /* !HAVE_GETADDRINFO */ | ||
| 1119 | 1163 | ||
| 1120 | #define CONNECT_ERROR "Could not connect to POP server: " | 1164 | #define CONNECT_ERROR "Could not connect to POP server: " |
| 1121 | 1165 | ||
| 1122 | if (! *hostent->h_addr_list) | 1166 | if (! connect_ok) |
| 1123 | { | 1167 | { |
| 1124 | CLOSESOCKET (sock); | 1168 | CLOSESOCKET (sock); |
| 1125 | strcpy (pop_error, CONNECT_ERROR); | 1169 | strcpy (pop_error, CONNECT_ERROR); |
| @@ -1130,6 +1174,10 @@ socket_connection (host, flags) | |||
| 1130 | } | 1174 | } |
| 1131 | 1175 | ||
| 1132 | #ifdef KERBEROS | 1176 | #ifdef KERBEROS |
| 1177 | |||
| 1178 | realhost = alloca (strlen (hostent->h_name) + 1); | ||
| 1179 | strcpy (realhost, hostent->h_name); | ||
| 1180 | |||
| 1133 | #define KRB_ERROR "Kerberos error connecting to POP server: " | 1181 | #define KRB_ERROR "Kerberos error connecting to POP server: " |
| 1134 | if (! (flags & POP_NO_KERBEROS)) | 1182 | if (! (flags & POP_NO_KERBEROS)) |
| 1135 | { | 1183 | { |
| @@ -1157,7 +1205,7 @@ socket_connection (host, flags) | |||
| 1157 | if (rem = krb5_cc_get_principal (kcontext, ccdef, &client)) | 1205 | if (rem = krb5_cc_get_principal (kcontext, ccdef, &client)) |
| 1158 | goto krb5error; | 1206 | goto krb5error; |
| 1159 | 1207 | ||
| 1160 | for (cp = hostent->h_name; *cp; cp++) | 1208 | for (cp = realhost; *cp; cp++) |
| 1161 | { | 1209 | { |
| 1162 | if (isupper (*cp)) | 1210 | if (isupper (*cp)) |
| 1163 | { | 1211 | { |
| @@ -1165,7 +1213,7 @@ socket_connection (host, flags) | |||
| 1165 | } | 1213 | } |
| 1166 | } | 1214 | } |
| 1167 | 1215 | ||
| 1168 | if (rem = krb5_sname_to_principal (kcontext, hostent->h_name, | 1216 | if (rem = krb5_sname_to_principal (kcontext, realhost, |
| 1169 | POP_SERVICE, FALSE, &server)) | 1217 | POP_SERVICE, FALSE, &server)) |
| 1170 | goto krb5error; | 1218 | goto krb5error; |
| 1171 | 1219 | ||
| @@ -1210,7 +1258,6 @@ socket_connection (host, flags) | |||
| 1210 | } | 1258 | } |
| 1211 | #else /* ! KERBEROS5 */ | 1259 | #else /* ! KERBEROS5 */ |
| 1212 | ticket = (KTEXT) malloc (sizeof (KTEXT_ST)); | 1260 | ticket = (KTEXT) malloc (sizeof (KTEXT_ST)); |
| 1213 | realhost = strdup (hostent->h_name); | ||
| 1214 | rem = krb_sendauth (0L, sock, ticket, "pop", realhost, | 1261 | rem = krb_sendauth (0L, sock, ticket, "pop", realhost, |
| 1215 | (char *) krb_realmofhost (realhost), | 1262 | (char *) krb_realmofhost (realhost), |
| 1216 | (unsigned long) 0, &msg_data, &cred, schedule, | 1263 | (unsigned long) 0, &msg_data, &cred, schedule, |
| @@ -1218,7 +1265,6 @@ socket_connection (host, flags) | |||
| 1218 | (struct sockaddr_in *) 0, | 1265 | (struct sockaddr_in *) 0, |
| 1219 | "KPOPV0.1"); | 1266 | "KPOPV0.1"); |
| 1220 | free ((char *) ticket); | 1267 | free ((char *) ticket); |
| 1221 | free (realhost); | ||
| 1222 | if (rem != KSUCCESS) | 1268 | if (rem != KSUCCESS) |
| 1223 | { | 1269 | { |
| 1224 | strcpy (pop_error, KRB_ERROR); | 1270 | strcpy (pop_error, KRB_ERROR); |