diff options
Diffstat (limited to 'ares__get_hostent.c')
-rw-r--r-- | ares__get_hostent.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/ares__get_hostent.c b/ares__get_hostent.c new file mode 100644 index 0000000..bba3b0e --- /dev/null +++ b/ares__get_hostent.c @@ -0,0 +1,171 @@ +/* Copyright 1998 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +static const char rcsid[] = "$Id$"; + +#include <sys/types.h> + +#ifdef WIN32 + +#else +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include "ares.h" +#include "ares_private.h" + +int ares__get_hostent(FILE *fp, struct hostent **host) +{ + char *line = NULL, *p, *q, *canonical, **alias; + int status, linesize, end_at_hostname, naliases; + struct in_addr addr; + struct hostent *hostent = NULL; + + while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) + { + /* Skip comment lines; terminate line at comment character. */ + if (*line == '#' || !*line) + continue; + p = strchr(line, '#'); + if (p) + *p = 0; + + /* Get the address part. */ + p = line; + while (*p && !isspace((unsigned char)*p)) + p++; + if (!*p) + continue; + *p = 0; + addr.s_addr = inet_addr(line); + if (addr.s_addr == INADDR_NONE) + continue; + + /* Get the canonical hostname. */ + p++; + while (isspace((unsigned char)*p)) + p++; + if (!*p) + continue; + q = p; + while (*q && !isspace((unsigned char)*q)) + q++; + end_at_hostname = (*q == 0); + *q = 0; + canonical = p; + + naliases = 0; + if (!end_at_hostname) + { + /* Count the aliases. */ + p = q + 1; + while (isspace((unsigned char)*p)) + p++; + while (*p) + { + while (*p && !isspace((unsigned char)*p)) + p++; + while (isspace((unsigned char)*p)) + p++; + naliases++; + } + } + + /* Allocate memory for the host structure. */ + hostent = malloc(sizeof(struct hostent)); + if (!hostent) + break; + hostent->h_aliases = NULL; + hostent->h_addr_list = NULL; + hostent->h_name = strdup(canonical); + if (!hostent->h_name) + break; + hostent->h_addr_list = malloc(2 * sizeof(char *)); + if (!hostent->h_addr_list) + break; + hostent->h_addr_list[0] = malloc(sizeof(struct in_addr)); + if (!hostent->h_addr_list[0]) + break; + hostent->h_aliases = malloc((naliases + 1) * sizeof(char *)); + if (!hostent->h_aliases) + break; + + /* Copy in aliases. */ + naliases = 0; + if (!end_at_hostname) + { + p = canonical + strlen(canonical) + 1; + while (isspace((unsigned char)*p)) + p++; + while (*p) + { + q = p; + while (*q && !isspace((unsigned char)*q)) + q++; + hostent->h_aliases[naliases] = malloc(q - p + 1); + if (hostent->h_aliases[naliases] == NULL) + break; + memcpy(hostent->h_aliases[naliases], p, q - p); + hostent->h_aliases[naliases][q - p] = 0; + p = q; + while (isspace((unsigned char)*p)) + p++; + naliases++; + } + if (*p) + break; + } + hostent->h_aliases[naliases] = NULL; + + hostent->h_addrtype = AF_INET; + hostent->h_length = sizeof(struct in_addr); + memcpy(hostent->h_addr_list[0], &addr, sizeof(struct in_addr)); + hostent->h_addr_list[1] = NULL; + *host = hostent; + free(line); + return ARES_SUCCESS; + } + free(line); + + if (status == ARES_SUCCESS) + { + /* Memory allocation failure; clean up. */ + if (hostent) + { + free((char *) hostent->h_name); + if (hostent->h_aliases) + { + for (alias = hostent->h_aliases; *alias; alias++) + free(*alias); + } + free(hostent->h_aliases); + if (hostent->h_addr_list) + free(hostent->h_addr_list[0]); + free(hostent->h_addr_list); + } + free(hostent); + return ARES_ENOMEM; + } + + return status; +} |