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 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
33 #include "ares_private.h"
34 #include "inet_net_pton.h"
36 int ares__get_hostent(FILE *fp, int family, struct hostent **host)
38 char *line = NULL, *p, *q, *canonical, **alias;
39 int status, linesize, end_at_hostname, naliases;
41 struct in6_addr addr6;
42 int addrlen = sizeof(struct in_addr);
43 struct hostent *hostent = NULL;
45 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
47 /* Skip comment lines; terminate line at comment character. */
48 if (*line == '#' || !*line)
50 p = strchr(line, '#');
54 /* Get the address part. */
56 while (*p && !ISSPACE(*p))
61 addr.s_addr = inet_addr(line);
62 if (addr.s_addr == INADDR_NONE)
64 if (ares_inet_pton(AF_INET6, line, &addr6) > 0)
66 if (family != AF_INET6)
68 addrlen = sizeof(struct in6_addr);
73 else if (family != AF_INET)
76 /* Get the canonical hostname. */
83 while (*q && !ISSPACE(*q))
85 end_at_hostname = (*q == 0);
92 /* Count the aliases. */
98 while (*p && !ISSPACE(*p))
106 /* Allocate memory for the host structure. */
107 hostent = malloc(sizeof(struct hostent));
110 hostent->h_aliases = NULL;
111 hostent->h_addr_list = NULL;
112 hostent->h_name = strdup(canonical);
113 if (!hostent->h_name)
115 hostent->h_addr_list = malloc(2 * sizeof(char *));
116 if (!hostent->h_addr_list)
118 hostent->h_addr_list[0] = malloc(addrlen);
119 if (!hostent->h_addr_list[0])
121 hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
122 if (!hostent->h_aliases)
125 /* Copy in aliases. */
127 if (!end_at_hostname)
129 p = canonical + strlen(canonical) + 1;
135 while (*q && !ISSPACE(*q))
137 hostent->h_aliases[naliases] = malloc(q - p + 1);
138 if (hostent->h_aliases[naliases] == NULL)
140 memcpy(hostent->h_aliases[naliases], p, q - p);
141 hostent->h_aliases[naliases][q - p] = 0;
150 hostent->h_aliases[naliases] = NULL;
152 hostent->h_addrtype = family;
153 hostent->h_length = addrlen;
154 if (family == AF_INET)
155 memcpy(hostent->h_addr_list[0], &addr, addrlen);
156 else if (family == AF_INET6)
157 memcpy(hostent->h_addr_list[0], &addr6, addrlen);
158 hostent->h_addr_list[1] = NULL;
166 if (status == ARES_SUCCESS)
168 /* Memory allocation failure; clean up. */
172 free((char *) hostent->h_name);
173 if (hostent->h_aliases)
175 for (alias = hostent->h_aliases; *alias; alias++)
178 if(hostent->h_aliases)
179 free(hostent->h_aliases);
180 if (hostent->h_addr_list && hostent->h_addr_list[0])
181 free(hostent->h_addr_list[0]);
182 if(hostent->h_addr_list)
183 free(hostent->h_addr_list);