# define SOCK_CONN_ERR -1
#endif
+#ifdef HAVE_GAI_STRERROR
+# define PHP_GAI_STRERROR(x) (gai_strerror(x))
+#else
+# define PHP_GAI_STRERROR(x) (php_gai_strerror(x))
+static char *php_gai_strerror(int code) {
+ static struct {
+ int code;
+ const char *msg;
+ } values[] = {
+# ifdef EAI_ADDRFAMILY
+ {EAI_ADDRFAMILY, "Address family for hostname not supported"},
+# endif
+ {EAI_AGAIN, "Temporary failure in name resolution"},
+ {EAI_BADFLAGS, "Bad value for ai_flags"},
+ {EAI_FAIL, "Non-recoverable failure in name resolution"},
+ {EAI_FAMILY, "ai_family not supported"},
+ {EAI_MEMORY, "Memory allocation failure"},
+# ifdef EAI_NODATA
+ {EAI_NODATA, "No address associated with hostname"},
+# endif
+ {EAI_NONAME, "Name or service not known"},
+ {EAI_SERVICE, "Servname not supported for ai_socktype"},
+ {EAI_SOCKTYPE, "ai_socktype not supported"},
+ {EAI_SYSTEM, "System error"},
+ {0, NULL}
+ };
+ int i;
+
+ for (i = 0; values[i].msg != NULL; i++) {
+ if (values[i].code == code) {
+ return (char *)values[i].msg;
+ }
+ }
+
+ return "Unknown error";
+}
+#endif
+
static void php_network_freeaddresses(struct sockaddr **sal)
{
struct sockaddr **sap;
static int php_network_getaddresses(const char *host, struct sockaddr ***sal)
{
struct sockaddr **sap;
-
- if (host != NULL) {
+
+ if (host == NULL) {
+ return -1;
+ }
+
+ {
#ifdef HAVE_GETADDRINFO
- struct addrinfo hints, *res, *sai;
+ struct addrinfo hints, *res, *sai;
int n;
- memset( &hints, '\0', sizeof(hints) );
- hints.ai_family = AF_UNSPEC;
- if (getaddrinfo(host, NULL, &hints, &res))
- return -1;
- sai = res;
- for (n=2; (sai = sai->ai_next) != NULL; n++);
- *sal = emalloc(n * sizeof(*sal));
- if (*sal == NULL)
+ memset(&hints, '\0', sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ if (n = getaddrinfo(host, NULL, &hints, &res)) {
+ php_error(E_WARNING, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n));
return -1;
+ }
- sai = res;
+ sai = res;
+ for (n=2; (sai = sai->ai_next) != NULL; n++);
+ *sal = emalloc(n * sizeof(*sal));
+ sai = res;
sap = *sal;
- do {
- switch (sai->ai_family) {
+ do {
+ switch (sai->ai_family) {
# ifdef HAVE_IPV6
- case AF_INET6: {
+ case AF_INET6:
*sap = emalloc(sizeof(struct sockaddr_in6));
- if (*sap == NULL) {
- freeaddrinfo(res);
- goto errexit;
- }
*(struct sockaddr_in6 *)*sap =
*((struct sockaddr_in6 *)sai->ai_addr);
- } break;
+ sap++;
+ break;
# endif
- case AF_INET: {
+ case AF_INET:
*sap = emalloc(sizeof(struct sockaddr_in));
- if (*sap == NULL) {
- freeaddrinfo(res);
- goto errexit;
- }
*(struct sockaddr_in *)*sap =
*((struct sockaddr_in *)sai->ai_addr);
- } break;
- default:
- *sap = NULL;
+ sap++;
break;
- }
- sap++;
- } while ((sai = sai->ai_next) != NULL);
- freeaddrinfo(res);
+ }
+ } while ((sai = sai->ai_next) != NULL);
+ freeaddrinfo(res);
#else
struct hostent *host_info;
struct in_addr in;
if (!inet_aton(host, &in)) {
/* XXX NOT THREAD SAFE */
host_info = gethostbyname(host);
- if (host_info == NULL)
+ if (host_info == NULL) {
+ php_error(E_WARNING, "php_network_getaddresses: gethostbyname failed");
return -1;
+ }
in = *((struct in_addr *) host_info->h_addr);
}
*sal = emalloc(2 * sizeof(*sal));
- if (*sal == NULL)
- return -1;
sap = *sal;
*sap = emalloc(sizeof(struct sockaddr_in));
- if (*sap == NULL)
- goto errexit;
-
(*sap)->sa_family = AF_INET;
((struct sockaddr_in *)*sap)->sin_addr = in;
sap++;
#endif
- *sap = NULL;
- return 0;
- errexit:
- php_network_freeaddresses(*sal);
- }
- return -1;
+ }
+ *sap = NULL;
+ return 0;
}
/*
sal++;
}
php_network_freeaddresses(psal);
+ php_error(E_WARNING, "php_hostconnect: connect failed");
return -1;
ok: