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.
19 #include <sys/types.h>
21 #if !defined(WIN32) || defined(WATT32)
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
34 #include "ares_private.h"
35 #include "inet_net_pton.h"
37 int ares__get_hostent(FILE *fp, int family, struct hostent **host)
39 char *line = NULL, *p, *q, *canonical, **alias;
40 int status, linesize, end_at_hostname, naliases;
42 struct in6_addr addr6;
43 int addrlen = sizeof(struct in_addr);
44 struct hostent *hostent = NULL;
46 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
48 /* Skip comment lines; terminate line at comment character. */
49 if (*line == '#' || !*line)
51 p = strchr(line, '#');
55 /* Get the address part. */
57 while (*p && !isspace((unsigned char)*p))
62 addr.s_addr = inet_addr(line);
63 if (addr.s_addr == INADDR_NONE)
65 if (ares_inet_pton(AF_INET6, line, &addr6) > 0)
67 if (family != AF_INET6)
69 addrlen = sizeof(struct in6_addr);
74 else if (family != AF_INET)
77 /* Get the canonical hostname. */
79 while (isspace((unsigned char)*p))
84 while (*q && !isspace((unsigned char)*q))
86 end_at_hostname = (*q == 0);
93 /* Count the aliases. */
95 while (isspace((unsigned char)*p))
99 while (*p && !isspace((unsigned char)*p))
101 while (isspace((unsigned char)*p))
107 /* Allocate memory for the host structure. */
108 hostent = malloc(sizeof(struct hostent));
111 hostent->h_aliases = NULL;
112 hostent->h_addr_list = NULL;
113 hostent->h_name = strdup(canonical);
114 if (!hostent->h_name)
116 hostent->h_addr_list = malloc(2 * sizeof(char *));
117 if (!hostent->h_addr_list)
119 hostent->h_addr_list[0] = malloc(addrlen);
120 if (!hostent->h_addr_list[0])
122 hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
123 if (!hostent->h_aliases)
126 /* Copy in aliases. */
128 if (!end_at_hostname)
130 p = canonical + strlen(canonical) + 1;
131 while (isspace((unsigned char)*p))
136 while (*q && !isspace((unsigned char)*q))
138 hostent->h_aliases[naliases] = malloc(q - p + 1);
139 if (hostent->h_aliases[naliases] == NULL)
141 memcpy(hostent->h_aliases[naliases], p, q - p);
142 hostent->h_aliases[naliases][q - p] = 0;
144 while (isspace((unsigned char)*p))
151 hostent->h_aliases[naliases] = NULL;
153 hostent->h_addrtype = family;
154 hostent->h_length = addrlen;
155 if (family == AF_INET)
156 memcpy(hostent->h_addr_list[0], &addr, addrlen);
157 else if (family == AF_INET6)
158 memcpy(hostent->h_addr_list[0], &addr6, addrlen);
159 hostent->h_addr_list[1] = NULL;
167 if (status == ARES_SUCCESS)
169 /* Memory allocation failure; clean up. */
173 free((char *) hostent->h_name);
174 if (hostent->h_aliases)
176 for (alias = hostent->h_aliases; *alias; alias++)
179 if(hostent->h_aliases)
180 free(hostent->h_aliases);
181 if (hostent->h_addr_list && hostent->h_addr_list[0])
182 free(hostent->h_addr_list[0]);
183 if(hostent->h_addr_list)
184 free(hostent->h_addr_list);