summaryrefslogtreecommitdiffstats
path: root/lib/gethostbyname.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gethostbyname.c')
-rw-r--r--lib/gethostbyname.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/lib/gethostbyname.c b/lib/gethostbyname.c
new file mode 100644
index 00000000..d151606d
--- /dev/null
+++ b/lib/gethostbyname.c
@@ -0,0 +1,228 @@
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
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
26#define _SVID_SOURCE 1 /* Need this to get gethostbyname_r() */
27
28#include <assert.h>
29
30#include <stdlib.h>
31#include <string.h>
32#include <netdb.h>
33#include <errno.h>
34
35#include "gethostbyname.h"
36
37#if HAVE_GETIPNODEBYNAME
38
39void
40free_ghbnctx (struct ghbnctx *ctx)
41{
42 assert (ctx != NULL);
43
44 if (ctx->hostent != NULL)
45 freehostent (ctx->hostent);
46}
47
48struct hostent *
49gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
50{
51 assert (ctx != NULL);
52
53 memset (ctx, 0, sizeof (struct ghbnctx));
54 ctx->hostent = getipnodebyname (host, AF_UNSPEC, AI_ADDRCONFIG, &ctx->h_err);
55 return ctx->hostent;
56}
57
58int
59h_error_ctx (struct ghbnctx *ctx)
60{
61 assert (ctx != NULL);
62
63 return ctx->h_err;
64}
65
66#elif HAVE_GETHOSTBYNAME_R == 6
67
68void
69free_ghbnctx (struct ghbnctx *ctx)
70{
71 assert (ctx != NULL);
72
73 if (ctx->hostbuf != NULL)
74 free (ctx->hostbuf);
75}
76
77struct hostent *
78gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
79{
80 struct hostent *hp;
81 char *tmp;
82 int err;
83
84 assert (ctx != NULL);
85
86 memset (ctx, 0, sizeof (struct ghbnctx));
87 ctx->hostbuf_len = 2048;
88 if ((ctx->hostbuf = malloc (ctx->hostbuf_len)) == NULL)
89 {
90 errno = ENOMEM;
91 return NULL;
92 }
93 while ((err = gethostbyname_r (host,
94 &ctx->hostent, ctx->hostbuf, ctx->hostbuf_len,
95 &hp, &ctx->h_err)) == ERANGE)
96 {
97 ctx->hostbuf_len += 1024;
98 if ((tmp = realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL)
99 {
100 errno = ENOMEM;
101 return NULL;
102 }
103 ctx->hostbuf = tmp;
104 }
105 if (err != 0)
106 {
107 errno = err;
108 return NULL;
109 }
110 return hp;
111}
112
113int
114h_error_ctx (struct ghbnctx *ctx)
115{
116 assert (ctx != NULL);
117
118 return ctx->h_err;
119}
120
121#elif HAVE_GETHOSTBYNAME_R == 5
122
123void
124free_ghbnctx (struct ghbnctx *ctx)
125{
126 assert (ctx != NULL);
127
128 if (ctx->hostbuf != NULL)
129 free (ctx->hostbuf);
130}
131
132struct hostent *
133gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
134{
135 struct hostent *hp;
136 char *tmp;
137
138 assert (ctx != NULL);
139
140 memset (ctx, 0, sizeof (struct ghbnctx));
141 ctx->hostbuf_len = 2048;
142 if ((ctx->hostbuf = malloc (ctx->hostbuf_len)) == NULL)
143 {
144 errno = ENOMEM;
145 return NULL;
146 }
147 while ((hp = gethostbyname_r (host, &ctx->hostent,
148 ctx->hostbuf, ctx->hostbuf_len,
149 &ctx->h_err)) == NULL && errno == ERANGE)
150 {
151 ctx->hostbuf_len += 1024;
152 if ((tmp = realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL)
153 {
154 errno = ENOMEM;
155 return NULL;
156 }
157 ctx->hostbuf = tmp;
158 }
159 return hp;
160}
161
162int
163h_error_ctx (struct ghbnctx *ctx)
164{
165 assert (ctx != NULL);
166
167 return ctx->h_err;
168}
169
170#elif HAVE_GETHOSTBYNAME_R == 3
171
172void
173free_ghbnctx (struct ghbnctx *ctx)
174{
175 assert (ctx != NULL);
176
177 /* FIXME: does this need to do anything? */
178}
179
180struct hostent *
181gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
182{
183 assert (ctx != NULL);
184
185 if (!gethostbyname_r (host, &ctx->hostent, &ctx->hostent_data))
186 {
187 ctx->h_err = h_errno; /* FIXME: is this correct? */
188 return NULL;
189 }
190 return &ctx->hostent;
191}
192
193int
194h_error_ctx (struct ghbnctx *ctx)
195{
196 assert (ctx != NULL);
197
198 return ctx->h_err;
199}
200
201#else
202
203void
204free_ghbnctx (struct ghbnctx *ctx __attribute__ ((unused)))
205{
206 assert (ctx != NULL);
207}
208
209struct hostent *
210gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
211{
212 struct hostent *hp;
213
214 hp = gethostbyname (host);
215 if (hp == NULL)
216 ctx->h_err = h_errno;
217 return hp;
218}
219
220int
221h_error_ctx (struct ghbnctx *ctx)
222{
223 assert (ctx != NULL);
224
225 return ctx->h_err;
226}
227
228#endif