Mercurial > hg > openjdk > jigsaw > bdb
view src/os/os_addrinfo.c @ 0:a1985f14b030
Initial load
author | chegar |
---|---|
date | Fri, 11 May 2012 10:42:02 +0100 |
parents | |
children |
line wrap: on
line source
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * * $Id$ */ #include "db_config.h" #include "db_int.h" /* * __os_getaddrinfo and __os_freeaddrinfo wrap the getaddrinfo and freeaddrinfo * calls, as well as the associated platform dependent error handling, mapping * the error return to a ANSI C/POSIX error return. */ /* * __os_getaddrinfo -- * * PUBLIC: #if defined(HAVE_REPLICATION_THREADS) * PUBLIC: int __os_getaddrinfo __P((ENV *, const char *, u_int, * PUBLIC: const char *, const ADDRINFO *, ADDRINFO **)); * PUBLIC: #endif */ 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, DB_STR_A("0153", "%s(%u): host lookup failed: %s", "%s %u %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); /* INADDR_NONE is not defined on Solaris 2.6, 2.7 or 2.8. */ #ifndef INADDR_NONE #define INADDR_NONE ((u_long)0xffffffff) #endif /* * Basic implementation of IPv4 component of getaddrinfo. * Limited to the functionality used by repmgr. */ 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(CHAR_STAR_CAST 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, DB_STR_A("0154", "%s(%u): host lookup failed", "%s %u"), nodename == NULL ? "" : nodename, port); return (__os_posix_err(ret)); #else /* * Historic UNIX systems used the h_errno * global variable to return gethostbyname * errors. The only function we currently * use that needs h_errno is gethostbyname, * so we deal with it here. * * hstrerror is not available on Solaris 2.6 * (it is in libresolv but is a private, * unexported symbol). */ #ifdef HAVE_HSTRERROR __db_errx(env, DB_STR_A("0155", "%s(%u): host lookup failed: %s", "%s %u %s"), nodename == NULL ? "" : nodename, port, hstrerror(h_errno)); #else __db_errx(env, DB_STR_A("0156", "%s(%u): host lookup failed: %d", "%s %u %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); } /* NOTREACHED */ #endif } memcpy(&(sin.sin_addr), hostaddr->h_addr, (size_t)hostaddr->h_length); } } else /* No host specified. */ 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 /* HAVE_GETADDRINFO */ } /* * __os_freeaddrinfo -- * * PUBLIC: #if defined(HAVE_REPLICATION_THREADS) * PUBLIC: void __os_freeaddrinfo __P((ENV *, ADDRINFO *)); * PUBLIC: #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 }