gethostbyname.c
Upload User: tsgydb
Upload Date: 2007-04-14
Package Size: 10674k
Code Size: 5k
Category:

MySQL

Development Platform:

Visual C++

  1. /*
  2.  * Copyright (c) 1985, 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *   notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *   notice, this list of conditions and the following disclaimer in the
  12.  *   documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *   must display the following acknowledgement:
  15.  * This product includes software developed by the University of
  16.  * California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *   may be used to endorse or promote products derived from this software
  19.  *   without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33. #if defined(LIBC_SCCS) && !defined(lint)
  34. /*static char *sccsid = "from: @(#)gethostbyname.c 6.45 (Berkeley) 2/24/91";*/
  35. static char *rcsid = "$Id$";
  36. #endif /* LIBC_SCCS and not lint */
  37. #include <pthread.h>
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <errno.h>
  42. #include <netdb.h>
  43. #include <netinet/in.h>
  44. #include <sys/socket.h>
  45. #include <resolv.h>
  46. #include "res_internal.h"
  47. static struct hostent *fake_hostent(const char *hostname, struct in_addr addr,
  48. struct hostent *result, char *buf,
  49. int bufsize, int *errval);
  50. static struct hostent *file_find_name(const char *name, struct hostent *result,
  51.   char *buf, int bufsize, int *errval);
  52. struct hostent *gethostbyname(const char *hostname)
  53. {
  54. struct res_data *data = _res_init();
  55. if (!data)
  56. return NULL;
  57. if (!data->buf) {
  58. data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE);
  59. if (!data->buf) {
  60. errno = 0;
  61. data->errval = NO_RECOVERY;
  62. return NULL;
  63. }
  64. }
  65. return gethostbyname_r(hostname, (struct hostent *) data->buf,
  66.    data->buf + sizeof(struct hostent), HOST_BUFSIZE,
  67.    &data->errval);
  68. }
  69. struct hostent *gethostbyname_r(const char *hostname, struct hostent *result,
  70. char *buf, int bufsize, int *errval)
  71. {
  72. struct in_addr addr;
  73. querybuf qbuf;
  74. const char *p;
  75. int n;
  76. /* Default failure condition is not a range error and not recoverable. */
  77. errno = 0;
  78. *errval = NO_RECOVERY;
  79. /* Check for all-numeric hostname with no trailing dot. */
  80. if (isdigit(hostname[0])) {
  81. p = hostname;
  82. while (*p && (isdigit(*p) || *p == '.'))
  83. p++;
  84. if (!*p && p[-1] != '.') {
  85. /* Looks like an IP address; convert it. */
  86. if (inet_aton(hostname, &addr) == -1) {
  87. *errval = HOST_NOT_FOUND;
  88. return NULL;
  89. }
  90. return fake_hostent(hostname, addr, result, buf, bufsize, errval);
  91. }
  92. }
  93. /* Do the search. */
  94. n = res_search(hostname, C_IN, T_A, qbuf.buf, sizeof(qbuf));
  95. if (n >= 0)
  96. return _res_parse_answer(&qbuf, n, 0, result, buf, bufsize, errval);
  97. else if (errno == ECONNREFUSED)
  98. return file_find_name(hostname, result, buf, bufsize, errval);
  99. else
  100. return NULL;
  101. }
  102. static struct hostent *fake_hostent(const char *hostname, struct in_addr addr,
  103. struct hostent *result, char *buf,
  104. int bufsize, int *errval)
  105. {
  106. int len = strlen(hostname);
  107. char *name, *addr_ptr;
  108. if (SP(SP(SP(buf, char, len + 1), addr, 1), char *, 3) > buf + bufsize) {
  109. errno = ERANGE;
  110. return NULL;
  111. }
  112. /* Copy faked name and address into buffer. */
  113. strcpy(buf, hostname);
  114. name = buf;
  115. buf = ALIGN(buf + len + 1, addr);
  116. *((struct in_addr *) buf) = addr;
  117. addr_ptr = buf;
  118. buf = ALIGN(buf + sizeof(addr), char *);
  119. ((char **) buf)[0] = addr_ptr;
  120. ((char **) buf)[1] = NULL;
  121. ((char **) buf)[2] = NULL;
  122. result->h_name = name;
  123. result->h_aliases = ((char **) buf) + 2;
  124. result->h_addrtype = AF_INET;
  125. result->h_length = sizeof(addr);
  126. result->h_addr_list = (char **) buf;
  127. return result;
  128. }
  129. static struct hostent *file_find_name(const char *name, struct hostent *result,
  130.       char *buf, int bufsize, int *errval)
  131. {
  132. char **alias;
  133. FILE *fp = NULL;
  134. pthread_mutex_lock(&host_iterate_lock);
  135. sethostent(0);
  136. while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) {
  137. /* Check the entry's name and aliases against the given name. */
  138. if (strcasecmp(result->h_name, name) == 0)
  139. break;
  140. for (alias = result->h_aliases; *alias; alias++) {
  141. if (strcasecmp(*alias, name) == 0)
  142.   goto end; /* Josip Gracin */
  143. }
  144. }
  145. end:
  146. pthread_mutex_unlock(&host_iterate_lock);
  147. if (!result && errno != ERANGE)
  148. *errval = HOST_NOT_FOUND;
  149. return result;
  150. }