3 /* Copyright 1998 by the Massachusetts Institute of Technology.
5 * Permission to use, copy, modify, and distribute this
6 * software and its documentation for any purpose and without
7 * fee is hereby granted, provided that the above copyright
8 * notice appear in all copies and that both that copyright
9 * notice and this permission notice appear in supporting
10 * documentation, and that the name of M.I.T. not be used in
11 * advertising or publicity pertaining to distribution of the
12 * software without specific, written prior permission.
13 * M.I.T. makes no representations about the suitability of
14 * this software for any purpose. It is provided "as is"
15 * without express or implied warranty.
20 #if !defined(WIN32) || defined(WATT32)
21 #ifdef HAVE_SYS_SOCKET_H
22 #include <sys/socket.h>
24 #ifdef HAVE_NETINET_IN_H
25 #include <netinet/in.h>
30 #ifdef HAVE_ARPA_INET_H
31 #include <arpa/inet.h>
41 #include "inet_net_pton.h"
42 #include "ares_private.h"
44 int ares__get_hostent(FILE *fp, int family, struct hostent **host)
46 char *line = NULL, *p, *q, *canonical, **alias;
47 int status, linesize, end_at_hostname, naliases;
49 struct in6_addr addr6;
50 size_t addrlen = sizeof(struct in_addr);
51 struct hostent *hostent = NULL;
53 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
55 /* Skip comment lines; terminate line at comment character. */
56 if (*line == '#' || !*line)
58 p = strchr(line, '#');
62 /* Get the address part. */
64 while (*p && !ISSPACE(*p))
69 addr.s_addr = inet_addr(line);
70 if (addr.s_addr == INADDR_NONE)
72 /* It wasn't an AF_INET dotted address, then AF_UNSPEC and AF_INET6
73 families are subject for this further check */
74 if ((family != AF_INET) &&
75 (ares_inet_pton(AF_INET6, line, &addr6) > 0)) {
76 addrlen = sizeof(struct in6_addr);
82 else if (family == AF_UNSPEC)
83 family = AF_INET; /* now confirmed! */
84 else if (family != AF_INET)
85 /* unknown, keep moving */
88 /* Get the canonical hostname. */
95 while (*q && !ISSPACE(*q))
97 end_at_hostname = (*q == 0);
102 if (!end_at_hostname)
104 /* Count the aliases. */
110 while (*p && !ISSPACE(*p))
118 /* Allocate memory for the host structure. */
119 hostent = malloc(sizeof(struct hostent));
122 hostent->h_aliases = NULL;
123 hostent->h_addr_list = NULL;
124 hostent->h_name = strdup(canonical);
125 if (!hostent->h_name)
127 hostent->h_addr_list = malloc(2 * sizeof(char *));
128 if (!hostent->h_addr_list)
130 hostent->h_addr_list[0] = malloc(addrlen);
131 if (!hostent->h_addr_list[0])
133 hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
134 if (!hostent->h_aliases)
137 /* Copy in aliases. */
139 if (!end_at_hostname)
141 p = canonical + strlen(canonical) + 1;
147 while (*q && !ISSPACE(*q))
149 hostent->h_aliases[naliases] = malloc(q - p + 1);
150 if (hostent->h_aliases[naliases] == NULL)
152 memcpy(hostent->h_aliases[naliases], p, q - p);
153 hostent->h_aliases[naliases][q - p] = 0;
162 hostent->h_aliases[naliases] = NULL;
164 hostent->h_addrtype = family;
165 hostent->h_length = (int)addrlen;
166 if (family == AF_INET)
167 memcpy(hostent->h_addr_list[0], &addr, addrlen);
168 else if (family == AF_INET6)
169 memcpy(hostent->h_addr_list[0], &addr6, addrlen);
170 hostent->h_addr_list[1] = NULL;
178 if (status == ARES_SUCCESS)
180 /* Memory allocation failure; clean up. */
184 free((char *) hostent->h_name);
185 if (hostent->h_aliases)
187 for (alias = hostent->h_aliases; *alias; alias++)
190 if(hostent->h_aliases)
191 free(hostent->h_aliases);
192 if (hostent->h_addr_list && hostent->h_addr_list[0])
193 free(hostent->h_addr_list[0]);
194 if(hostent->h_addr_list)
195 free(hostent->h_addr_list);