]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - libares/ares__get_hostent.c
need automake as a build-dep, even though we don't use most of it
[1ts-debian.git] / libares / ares__get_hostent.c
1 /* Copyright 1998 by the Massachusetts Institute of Technology.
2  *
3  * Permission to use, copy, modify, and distribute this
4  * software and its documentation for any purpose and without
5  * fee is hereby granted, provided that the above copyright
6  * notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting
8  * documentation, and that the name of M.I.T. not be used in
9  * advertising or publicity pertaining to distribution of the
10  * software without specific, written prior permission.
11  * M.I.T. makes no representations about the suitability of
12  * this software for any purpose.  It is provided "as is"
13  * without express or implied warranty.
14  */
15
16 static const char rcsid[] = "$Id: ares__get_hostent.c,v 1.3 2000/02/17 18:39:58 ghudson Exp $";
17
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <netdb.h>
27 #include "ares.h"
28 #include "ares_private.h"
29
30 int ares__get_hostent(FILE *fp, struct hostent **host)
31 {
32   char *line = NULL, *p, *q, *canonical, **alias;
33   int status, linesize, end_at_hostname, naliases;
34   struct in_addr addr;
35   struct hostent *hostent = NULL;
36
37   while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
38     {
39       /* Skip comment lines; terminate line at comment character. */
40       if (*line == '#' || !*line)
41         continue;
42       p = strchr(line, '#');
43       if (p)
44         *p = 0;
45
46       /* Get the address part. */
47       p = line;
48       while (*p && !isspace((unsigned char)*p))
49         p++;
50       if (!*p)
51         continue;
52       *p = 0;
53       addr.s_addr = inet_addr(line);
54       if (addr.s_addr == INADDR_NONE)
55         continue;
56
57       /* Get the canonical hostname. */
58       p++;
59       while (isspace((unsigned char)*p))
60         p++;
61       if (!*p)
62         continue;
63       q = p;
64       while (*q && !isspace((unsigned char)*q))
65         q++;
66       end_at_hostname = (*q == 0);
67       *q = 0;
68       canonical = p;
69
70       naliases = 0;
71       if (!end_at_hostname)
72         {
73           /* Count the aliases. */
74           p = q + 1;
75           while (isspace((unsigned char)*p))
76             p++;
77           while (*p)
78             {
79               while (*p && !isspace((unsigned char)*p))
80                 p++;
81               while (isspace((unsigned char)*p))
82                 p++;
83               naliases++;
84             }
85         }
86
87       /* Allocate memory for the host structure. */
88       hostent = malloc(sizeof(struct hostent));
89       if (!hostent)
90         break;
91       hostent->h_aliases = NULL;
92       hostent->h_addr_list = NULL;
93       hostent->h_name = strdup(canonical);
94       if (!hostent->h_name)
95         break;
96       hostent->h_addr_list = malloc(2 * sizeof(char *));
97       if (!hostent->h_addr_list)
98         break;
99       hostent->h_addr_list[0] = malloc(sizeof(struct in_addr));
100       if (!hostent->h_addr_list[0])
101         break;
102       hostent->h_aliases = malloc((naliases + 1) * sizeof(char *));
103       if (!hostent->h_aliases)
104         break;
105
106       /* Copy in aliases. */
107       naliases = 0;
108       if (!end_at_hostname)
109         {
110           p = canonical + strlen(canonical) + 1;
111           while (isspace((unsigned char)*p))
112             p++;
113           while (*p)
114             {
115               q = p;
116               while (*q && !isspace((unsigned char)*q))
117                 q++;
118               hostent->h_aliases[naliases] = malloc(q - p + 1);
119               if (hostent->h_aliases[naliases] == NULL)
120                 break;
121               memcpy(hostent->h_aliases[naliases], p, q - p);
122               hostent->h_aliases[naliases][q - p] = 0;
123               p = q;
124               while (isspace((unsigned char)*p))
125                 p++;
126               naliases++;
127             }
128           if (*p)
129             break;
130         }
131       hostent->h_aliases[naliases] = NULL;
132
133       hostent->h_addrtype = AF_INET;
134       hostent->h_length = sizeof(struct in_addr);
135       memcpy(hostent->h_addr_list[0], &addr, sizeof(struct in_addr));
136       hostent->h_addr_list[1] = NULL;
137       *host = hostent;
138       free(line);
139       return ARES_SUCCESS;
140     }
141   free(line);
142
143   if (status == ARES_SUCCESS)
144     {
145       /* Memory allocation failure; clean up. */
146       if (hostent)
147         {
148           free((char *) hostent->h_name);
149           if (hostent->h_aliases)
150             {
151               for (alias = hostent->h_aliases; *alias; alias++)
152                 free(*alias);
153             }
154           free(hostent->h_aliases);
155           if (hostent->h_addr_list)
156             free(hostent->h_addr_list[0]);
157           free(hostent->h_addr_list);
158         }
159       free(hostent);
160       return ARES_ENOMEM;
161     }
162
163   return status;
164 }