#include "db_config.h"
#define __INCLUDE_NETWORKING 1
#include "db_int.h"
int
__os_getaddrinfo(env, nodename, port, servname, hints, res)
ENV *env;
const char *nodename, *servname;
u_int port;
const ADDRINFO *hints;
ADDRINFO **res;
{
#ifdef HAVE_GETADDRINFO
int ret;
if ((ret = getaddrinfo(nodename, servname, hints, res)) == 0)
return (0);
__db_errx(env, "%s(%u): host lookup failed: %s",
nodename == NULL ? "" : nodename, port,
#ifdef DB_WIN32
gai_strerrorA(ret));
#else
gai_strerror(ret));
#endif
return (__os_posix_err(ret));
#else
ADDRINFO *answer;
struct hostent *hostaddr;
struct sockaddr_in sin;
u_int32_t tmpaddr;
int ret;
COMPQUIET(hints, NULL);
COMPQUIET(servname, NULL);
#ifndef INADDR_NONE
#define INADDR_NONE ((u_long)0xffffffff)
#endif
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
if (nodename) {
if (nodename[0] == '\0')
sin.sin_addr.s_addr = htonl(INADDR_ANY);
else if ((tmpaddr = inet_addr(nodename)) != INADDR_NONE) {
sin.sin_addr.s_addr = tmpaddr;
} else {
hostaddr = gethostbyname(nodename);
if (hostaddr == NULL) {
#ifdef DB_WIN32
ret = __os_get_neterr();
__db_syserr(env, ret,
"%s(%u): host lookup failed",
nodename == NULL ? "" : nodename, port);
return (__os_posix_err(ret));
#else
#ifdef HAVE_HSTRERROR
__db_errx(env,
"%s(%u): host lookup failed: %s",
nodename == NULL ? "" : nodename, port,
hstrerror(h_errno));
#else
__db_errx(env,
"%s(%u): host lookup failed: %d",
nodename == NULL ? "" : nodename, port,
h_errno);
#endif
switch (h_errno) {
case HOST_NOT_FOUND:
case NO_DATA:
return (EHOSTUNREACH);
case TRY_AGAIN:
return (EAGAIN);
case NO_RECOVERY:
default:
return (EFAULT);
}
#endif
}
memcpy(&(sin.sin_addr),
hostaddr->h_addr, (size_t)hostaddr->h_length);
}
} else
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons((u_int16_t)port);
if ((ret = __os_calloc(env, 1, sizeof(ADDRINFO), &answer)) != 0)
return (ret);
if ((ret = __os_malloc(env, sizeof(sin), &answer->ai_addr)) != 0) {
__os_free(env, answer);
return (ret);
}
answer->ai_family = AF_INET;
answer->ai_protocol = IPPROTO_TCP;
answer->ai_socktype = SOCK_STREAM;
answer->ai_addrlen = sizeof(sin);
memcpy(answer->ai_addr, &sin, sizeof(sin));
*res = answer;
return (0);
#endif
}
void
__os_freeaddrinfo(env, ai)
ENV *env;
ADDRINFO *ai;
{
#ifdef HAVE_GETADDRINFO
COMPQUIET(env, NULL);
freeaddrinfo(ai);
#else
ADDRINFO *next, *tmpaddr;
for (next = ai; next != NULL; next = tmpaddr) {
if (next->ai_canonname != NULL)
__os_free(env, next->ai_canonname);
if (next->ai_addr != NULL)
__os_free(env, next->ai_addr);
tmpaddr = next->ai_next;
__os_free(env, next);
}
#endif
}