]> Pileus Git - ~andy/fetchmail/blob - libesmtp/gethostbyname.c
Merge branch 'legacy_63'
[~andy/fetchmail] / libesmtp / gethostbyname.c
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_GETHOSTBYNAME_R == 6
38
39 void
40 free_ghbnctx (struct ghbnctx *ctx)
41 {
42   assert (ctx != NULL);
43
44   if (ctx->hostbuf != NULL)
45     free (ctx->hostbuf);
46 }
47
48 struct hostent *
49 gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
50 {
51   struct hostent *hp;
52   char *tmp;
53   int err;
54
55   assert (ctx != NULL);
56
57   memset (ctx, 0, sizeof (struct ghbnctx));
58   ctx->hostbuf_len = 2048;
59   if ((ctx->hostbuf = (char *)malloc (ctx->hostbuf_len)) == NULL)
60     {
61       errno = ENOMEM;
62       return NULL;
63     }
64   while ((err = gethostbyname_r (host,
65                                  &ctx->hostent, ctx->hostbuf, ctx->hostbuf_len,
66                                  &hp, &ctx->h_err)) == ERANGE)
67     {
68       ctx->hostbuf_len += 1024;
69       if ((tmp = (char *)realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL)
70         {
71           errno = ENOMEM;
72           return NULL;
73         }
74       ctx->hostbuf = tmp;
75     }
76   if (err != 0)
77     {
78       errno = err;
79       return NULL;
80     }
81   return hp;
82 }
83
84 int
85 h_error_ctx (struct ghbnctx *ctx)
86 {
87   assert (ctx != NULL);
88
89   return ctx->h_err;
90 }
91
92 #elif HAVE_GETHOSTBYNAME_R == 5
93
94 void
95 free_ghbnctx (struct ghbnctx *ctx)
96 {
97   assert (ctx != NULL);
98
99   if (ctx->hostbuf != NULL)
100     free (ctx->hostbuf);
101 }
102
103 struct hostent *
104 gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
105 {
106   struct hostent *hp;
107   char *tmp;
108
109   assert (ctx != NULL);
110
111   memset (ctx, 0, sizeof (struct ghbnctx));
112   ctx->hostbuf_len = 2048;
113   if ((ctx->hostbuf = malloc (ctx->hostbuf_len)) == NULL)
114     {
115       errno = ENOMEM;
116       return NULL;
117     }
118   while ((hp = gethostbyname_r (host, &ctx->hostent,
119                                 ctx->hostbuf, ctx->hostbuf_len,
120                                 &ctx->h_err)) == NULL && errno == ERANGE)
121     {
122       ctx->hostbuf_len += 1024;
123       if ((tmp = realloc (ctx->hostbuf, ctx->hostbuf_len)) == NULL)
124         {
125           errno = ENOMEM;
126           return NULL;
127         }
128       ctx->hostbuf = tmp;
129     }
130   return hp;
131 }
132
133 int
134 h_error_ctx (struct ghbnctx *ctx)
135 {
136   assert (ctx != NULL);
137
138   return ctx->h_err;
139 }
140
141 #elif HAVE_GETHOSTBYNAME_R == 3
142
143 void
144 free_ghbnctx (struct ghbnctx *ctx)
145 {
146   assert (ctx != NULL);
147
148   /* FIXME: does this need to do anything? */
149 }
150
151 struct hostent *
152 gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
153 {
154   assert (ctx != NULL);
155
156   if (!gethostbyname_r (host, &ctx->hostent, &ctx->hostent_data))
157     {
158       ctx->h_err = h_errno;     /* FIXME: is this correct? */
159       return NULL;
160     }
161   return &ctx->hostent;
162 }
163   
164 int
165 h_error_ctx (struct ghbnctx *ctx)
166 {
167   assert (ctx != NULL);
168
169   return ctx->h_err;
170 }
171
172 #else
173
174 void
175 free_ghbnctx (struct ghbnctx *ctx )
176 {
177   assert (ctx != NULL);
178 }
179
180 struct hostent *
181 gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
182 {
183   struct hostent *hp;
184
185   hp = gethostbyname (host);
186   if (hp == NULL)
187     ctx->h_err = h_errno;
188   return hp;
189 }
190
191 int
192 h_error_ctx (struct ghbnctx *ctx)
193 {
194   assert (ctx != NULL);
195
196   return ctx->h_err;
197 }
198
199 #endif