4
0

gethostbyname.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * This file is a ghastly hack because nobody can agree on
  3. * gethostbyname_r()'s prototype.
  4. *
  5. * Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. * $Id$
  22. */
  23. #ifdef HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26. #define _SVID_SOURCE 1 /* Need this to get gethostbyname_r() */
  27. #include <assert.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <netdb.h>
  31. #include <errno.h>
  32. #include "gethostbyname.h"
  33. #if HAVE_GETIPNODEBYNAME
  34. void
  35. free_ghbnctx (struct ghbnctx *ctx)
  36. {
  37. assert (ctx != NULL);
  38. if (ctx->hostent != NULL)
  39. freehostent (ctx->hostent);
  40. }
  41. struct hostent *
  42. gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
  43. {
  44. assert (ctx != NULL);
  45. memset (ctx, 0, sizeof (struct ghbnctx));
  46. ctx->hostent = getipnodebyname (host, AF_UNSPEC, AI_ADDRCONFIG, &ctx->h_err);
  47. return ctx->hostent;
  48. }
  49. int
  50. h_error_ctx (struct ghbnctx *ctx)
  51. {
  52. assert (ctx != NULL);
  53. return ctx->h_err;
  54. }
  55. #elif HAVE_GETHOSTBYNAME_R == 6
  56. void
  57. free_ghbnctx (struct ghbnctx *ctx)
  58. {
  59. assert (ctx != NULL);
  60. if (ctx->hostbuf != NULL)
  61. free (ctx->hostbuf);
  62. }
  63. struct hostent *
  64. gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
  65. {
  66. struct hostent *hp;
  67. char *tmp;
  68. int err;
  69. assert (ctx != NULL);
  70. memset (ctx, 0, sizeof (struct ghbnctx));
  71. ctx->hostbuf_len = 2048;
  72. if ((ctx->hostbuf = malloc (ctx->hostbuf_len)) == NULL)
  73. {
  74. errno = ENOMEM;
  75. return NULL;
  76. }
  77. while ((err = gethostbyname_r (host,
  78. &ctx->hostent, ctx->hostbuf, ctx->hostbuf_len,
  79. &hp, &ctx->h_err)) == ERANGE)
  80. {
  81. ctx->hostbuf_len += 1024;
  82. if ((tmp = realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL)
  83. {
  84. errno = ENOMEM;
  85. return NULL;
  86. }
  87. ctx->hostbuf = tmp;
  88. }
  89. if (err != 0)
  90. {
  91. errno = err;
  92. return NULL;
  93. }
  94. return hp;
  95. }
  96. int
  97. h_error_ctx (struct ghbnctx *ctx)
  98. {
  99. assert (ctx != NULL);
  100. return ctx->h_err;
  101. }
  102. #elif HAVE_GETHOSTBYNAME_R == 5
  103. void
  104. free_ghbnctx (struct ghbnctx *ctx)
  105. {
  106. assert (ctx != NULL);
  107. if (ctx->hostbuf != NULL)
  108. free (ctx->hostbuf);
  109. }
  110. struct hostent *
  111. gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
  112. {
  113. struct hostent *hp;
  114. char *tmp;
  115. assert (ctx != NULL);
  116. memset (ctx, 0, sizeof (struct ghbnctx));
  117. ctx->hostbuf_len = 2048;
  118. if ((ctx->hostbuf = malloc (ctx->hostbuf_len)) == NULL)
  119. {
  120. errno = ENOMEM;
  121. return NULL;
  122. }
  123. while ((hp = gethostbyname_r (host, &ctx->hostent,
  124. ctx->hostbuf, ctx->hostbuf_len,
  125. &ctx->h_err)) == NULL && errno == ERANGE)
  126. {
  127. ctx->hostbuf_len += 1024;
  128. if ((tmp = realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL)
  129. {
  130. errno = ENOMEM;
  131. return NULL;
  132. }
  133. ctx->hostbuf = tmp;
  134. }
  135. return hp;
  136. }
  137. int
  138. h_error_ctx (struct ghbnctx *ctx)
  139. {
  140. assert (ctx != NULL);
  141. return ctx->h_err;
  142. }
  143. #elif HAVE_GETHOSTBYNAME_R == 3
  144. void
  145. free_ghbnctx (struct ghbnctx *ctx)
  146. {
  147. assert (ctx != NULL);
  148. /* FIXME: does this need to do anything? */
  149. }
  150. struct hostent *
  151. gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
  152. {
  153. assert (ctx != NULL);
  154. if (!gethostbyname_r (host, &ctx->hostent, &ctx->hostent_data))
  155. {
  156. ctx->h_err = h_errno; /* FIXME: is this correct? */
  157. return NULL;
  158. }
  159. return &ctx->hostent;
  160. }
  161. int
  162. h_error_ctx (struct ghbnctx *ctx)
  163. {
  164. assert (ctx != NULL);
  165. return ctx->h_err;
  166. }
  167. #else
  168. void
  169. free_ghbnctx (struct ghbnctx *ctx __attribute__ ((unused)))
  170. {
  171. assert (ctx != NULL);
  172. }
  173. struct hostent *
  174. gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
  175. {
  176. struct hostent *hp;
  177. hp = gethostbyname (host);
  178. if (hp == NULL)
  179. ctx->h_err = h_errno;
  180. return hp;
  181. }
  182. int
  183. h_error_ctx (struct ghbnctx *ctx)
  184. {
  185. assert (ctx != NULL);
  186. return ctx->h_err;
  187. }
  188. #endif