ares__get_hostent.c
Go to the documentation of this file.
1 
2 /* Copyright 1998, 2011 by the Massachusetts Institute of Technology.
3  *
4  * Permission to use, copy, modify, and distribute this
5  * software and its documentation for any purpose and without
6  * fee is hereby granted, provided that the above copyright
7  * notice appear in all copies and that both that copyright
8  * notice and this permission notice appear in supporting
9  * documentation, and that the name of M.I.T. not be used in
10  * advertising or publicity pertaining to distribution of the
11  * software without specific, written prior permission.
12  * M.I.T. makes no representations about the suitability of
13  * this software for any purpose. It is provided "as is"
14  * without express or implied warranty.
15  */
16 
17 #include "ares_setup.h"
18 
19 #ifdef HAVE_NETINET_IN_H
20 # include <netinet/in.h>
21 #endif
22 #ifdef HAVE_NETDB_H
23 # include <netdb.h>
24 #endif
25 #ifdef HAVE_ARPA_INET_H
26 # include <arpa/inet.h>
27 #endif
28 
29 #include "ares.h"
30 #include "ares_inet_net_pton.h"
31 #include "ares_nowarn.h"
32 #include "ares_private.h"
33 
34 int ares__get_hostent(FILE *fp, int family, struct hostent **host)
35 {
36  char *line = NULL, *p, *q, **alias;
37  char *txtaddr, *txthost, *txtalias;
38  int status;
39  size_t addrlen, linesize, naliases;
40  struct ares_addr addr;
41  struct hostent *hostent = NULL;
42 
43  *host = NULL; /* Assume failure */
44 
45  /* Validate family */
46  switch (family) {
47  case AF_INET:
48  case AF_INET6:
49  case AF_UNSPEC:
50  break;
51  default:
52  return ARES_EBADFAMILY;
53  }
54 
55  while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
56  {
57 
58  /* Trim line comment. */
59  p = line;
60  while (*p && (*p != '#'))
61  p++;
62  *p = '\0';
63 
64  /* Trim trailing whitespace. */
65  q = p - 1;
66  while ((q >= line) && ISSPACE(*q))
67  q--;
68  *++q = '\0';
69 
70  /* Skip leading whitespace. */
71  p = line;
72  while (*p && ISSPACE(*p))
73  p++;
74  if (!*p)
75  /* Ignore line if empty. */
76  continue;
77 
78  /* Pointer to start of IPv4 or IPv6 address part. */
79  txtaddr = p;
80 
81  /* Advance past address part. */
82  while (*p && !ISSPACE(*p))
83  p++;
84  if (!*p)
85  /* Ignore line if reached end of line. */
86  continue;
87 
88  /* Null terminate address part. */
89  *p = '\0';
90 
91  /* Advance to host name */
92  p++;
93  while (*p && ISSPACE(*p))
94  p++;
95  if (!*p)
96  /* Ignore line if reached end of line. */
97  continue; /* LCOV_EXCL_LINE: trailing whitespace already stripped */
98 
99  /* Pointer to start of host name. */
100  txthost = p;
101 
102  /* Advance past host name. */
103  while (*p && !ISSPACE(*p))
104  p++;
105 
106  /* Pointer to start of first alias. */
107  txtalias = NULL;
108  if (*p)
109  {
110  q = p + 1;
111  while (*q && ISSPACE(*q))
112  q++;
113  if (*q)
114  txtalias = q;
115  }
116 
117  /* Null terminate host name. */
118  *p = '\0';
119 
120  /* find out number of aliases. */
121  naliases = 0;
122  if (txtalias)
123  {
124  p = txtalias;
125  while (*p)
126  {
127  while (*p && !ISSPACE(*p))
128  p++;
129  while (*p && ISSPACE(*p))
130  p++;
131  naliases++;
132  }
133  }
134 
135  /* Convert address string to network address for the requested family. */
136  addrlen = 0;
137  addr.family = AF_UNSPEC;
138  addr.addrV4.s_addr = INADDR_NONE;
139  if ((family == AF_INET) || (family == AF_UNSPEC))
140  {
141  if (ares_inet_pton(AF_INET, txtaddr, &addr.addrV4) > 0)
142  {
143  /* Actual network address family and length. */
144  addr.family = AF_INET;
145  addrlen = sizeof(addr.addrV4);
146  }
147  }
148  if ((family == AF_INET6) || ((family == AF_UNSPEC) && (!addrlen)))
149  {
150  if (ares_inet_pton(AF_INET6, txtaddr, &addr.addrV6) > 0)
151  {
152  /* Actual network address family and length. */
153  addr.family = AF_INET6;
154  addrlen = sizeof(addr.addrV6);
155  }
156  }
157  if (!addrlen)
158  /* Ignore line if invalid address string for the requested family. */
159  continue;
160 
161  /*
162  ** Actual address family possible values are AF_INET and AF_INET6 only.
163  */
164 
165  /* Allocate memory for the hostent structure. */
166  hostent = ares_malloc(sizeof(struct hostent));
167  if (!hostent)
168  break;
169 
170  /* Initialize fields for out of memory condition. */
171  hostent->h_aliases = NULL;
172  hostent->h_addr_list = NULL;
173 
174  /* Copy official host name. */
175  hostent->h_name = ares_strdup(txthost);
176  if (!hostent->h_name)
177  break;
178 
179  /* Copy network address. */
180  hostent->h_addr_list = ares_malloc(2 * sizeof(char *));
181  if (!hostent->h_addr_list)
182  break;
183  hostent->h_addr_list[1] = NULL;
184  hostent->h_addr_list[0] = ares_malloc(addrlen);
185  if (!hostent->h_addr_list[0])
186  break;
187  if (addr.family == AF_INET)
188  memcpy(hostent->h_addr_list[0], &addr.addrV4, sizeof(addr.addrV4));
189  else
190  memcpy(hostent->h_addr_list[0], &addr.addrV6, sizeof(addr.addrV6));
191 
192  /* Copy aliases. */
193  hostent->h_aliases = ares_malloc((naliases + 1) * sizeof(char *));
194  if (!hostent->h_aliases)
195  break;
196  alias = hostent->h_aliases;
197  while (naliases)
198  *(alias + naliases--) = NULL;
199  *alias = NULL;
200  while (txtalias)
201  {
202  p = txtalias;
203  while (*p && !ISSPACE(*p))
204  p++;
205  q = p;
206  while (*q && ISSPACE(*q))
207  q++;
208  *p = '\0';
209  if ((*alias = ares_strdup(txtalias)) == NULL)
210  break;
211  alias++;
212  txtalias = *q ? q : NULL;
213  }
214  if (txtalias)
215  /* Alias memory allocation failure. */
216  break;
217 
218  /* Copy actual network address family and length. */
219  hostent->h_addrtype = aresx_sitoss(addr.family);
220  hostent->h_length = aresx_uztoss(addrlen);
221 
222  /* Free line buffer. */
223  ares_free(line);
224 
225  /* Return hostent successfully */
226  *host = hostent;
227  return ARES_SUCCESS;
228 
229  }
230 
231  /* If allocated, free line buffer. */
232  if (line)
233  ares_free(line);
234 
235  if (status == ARES_SUCCESS)
236  {
237  /* Memory allocation failure; clean up. */
238  if (hostent)
239  {
240  if (hostent->h_name)
241  ares_free((char *) hostent->h_name);
242  if (hostent->h_aliases)
243  {
244  for (alias = hostent->h_aliases; *alias; alias++)
245  ares_free(*alias);
246  ares_free(hostent->h_aliases);
247  }
248  if (hostent->h_addr_list)
249  {
250  if (hostent->h_addr_list[0])
251  ares_free(hostent->h_addr_list[0]);
252  ares_free(hostent->h_addr_list);
253  }
254  ares_free(hostent);
255  }
256  return ARES_ENOMEM;
257  }
258 
259  return status;
260 }
ARES_ENOMEM
#define ARES_ENOMEM
Definition: ares.h:117
ares_inet_pton
CARES_EXTERN int ares_inet_pton(int af, const char *src, void *dst)
Definition: inet_net_pton.c:418
aresx_uztoss
short aresx_uztoss(size_t uznum)
Definition: ares_nowarn.c:101
AF_INET6
#define AF_INET6
Definition: ares_setup.h:208
INADDR_NONE
#define INADDR_NONE
Definition: ares_private.h:43
ares_addr
Definition: ares_private.h:133
ares.h
ares_strdup
char * ares_strdup(const char *s1)
Definition: ares_strdup.c:23
ares_inet_net_pton.h
status
absl::Status status
Definition: rls.cc:251
xds_manager.p
p
Definition: xds_manager.py:60
ares__read_line
int ares__read_line(FILE *fp, char **buf, size_t *bufsize)
Definition: ares__read_line.c:31
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
ares_malloc
void *(* ares_malloc)(size_t size)=default_malloc
Definition: ares_library_init.c:58
ARES_EBADFAMILY
#define ARES_EBADFAMILY
Definition: ares.h:111
aresx_sitoss
short aresx_sitoss(int sinum)
Definition: ares_nowarn.c:119
ARES_SUCCESS
#define ARES_SUCCESS
Definition: ares.h:98
ares_setup.h
benchmark.FILE
FILE
Definition: benchmark.py:21
ares__get_hostent
int ares__get_hostent(FILE *fp, int family, struct hostent **host)
Definition: ares__get_hostent.c:34
ares_free
void(* ares_free)(void *ptr)=default_free
Definition: ares_library_init.c:60
regen-readme.line
line
Definition: regen-readme.py:30
ares_private.h
ares_nowarn.h
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
ISSPACE
#define ISSPACE(x)
Definition: setup_once.h:275


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:43