Uninitialized vector entry?
[minix3.git] / lib / ip / gethostent.c
blob1a9aed20d2e8a1e9a6523ff24e22cb0a77e6b4b3
1 /* gethostent() - Interface to /etc/hosts Author: Kees J. Bot
2 * 31 May 1999
3 */
5 /* Prefix the functions defined here with underscores to distinguish them
6 * from the newer replacements in the resolver library.
7 */
8 #define sethostent _sethostent
9 #define endhostent _endhostent
10 #define gethostent _gethostent
11 #define gethostbyname _gethostbyname
12 #define gethostbyaddr _gethostbyaddr
14 #define nil 0
15 #include <sys/types.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <net/gen/netdb.h>
19 #include <net/gen/in.h>
20 #include <net/gen/inet.h>
21 #include <net/gen/socket.h>
23 #define arraysize(a) (sizeof(a) / sizeof((a)[0]))
24 #define arraylimit(a) ((a) + arraysize(a))
25 #define isspace(c) ((unsigned) (c) <= ' ')
27 static char HOSTS[]= _PATH_HOSTS;
28 static char *hosts= HOSTS; /* Current hosts file. */
29 static FILE *hfp; /* Open hosts file. */
31 void sethostent(int stayopen)
32 /* Start search. (Same as ending it.) */
34 endhostent();
37 void endhostent(void)
38 /* End search and reinitialize. */
40 if (hfp != nil) {
41 fclose(hfp);
42 hfp= nil;
44 hosts= _PATH_HOSTS;
47 struct hostent *gethostent(void)
48 /* Return the next entry from the hosts files. */
50 static char line[256]; /* One line in a hosts file. */
51 static ipaddr_t addr; /* IP address found first on the line. */
52 static char *names[16]; /* Pointers to the words on the line. */
53 static char *addrs[2]= { /* List of IP addresses (just one.) */
54 (char *) &addr,
55 nil,
57 static struct hostent host = {
58 nil, /* h_name, will set to names[1]. */
59 names + 2, /* h_aliases, the rest of the names. */
60 AF_INET, /* h_addrtype */
61 sizeof(ipaddr_t), /* Size of an address in the address list. */
62 addrs, /* List of IP addresses. */
64 static char nexthosts[128]; /* Next hosts file to include. */
65 char *lp, **np;
66 int c;
68 for (;;) {
69 if (hfp == nil) {
70 /* No hosts file open, try to open the next one. */
71 if (hosts == 0) return nil;
72 if ((hfp= fopen(hosts, "r")) == nil) { hosts= nil; continue; }
75 /* Read a line. */
76 lp= line;
77 while ((c= getc(hfp)) != EOF && c != '\n') {
78 if (lp < arraylimit(line)) *lp++= c;
81 /* EOF? Then close and prepare for reading the next file. */
82 if (c == EOF) {
83 fclose(hfp);
84 hfp= nil;
85 hosts= nil;
86 continue;
89 if (lp == arraylimit(line)) continue;
90 *lp= 0;
92 /* Break the line up in words. */
93 np= names;
94 lp= line;
95 for (;;) {
96 while (isspace(*lp) && *lp != 0) lp++;
97 if (*lp == 0 || *lp == '#') break;
98 if (np == arraylimit(names)) break;
99 *np++= lp;
100 while (!isspace(*lp) && *lp != 0) lp++;
101 if (*lp == 0) break;
102 *lp++= 0;
105 if (np == arraylimit(names)) continue;
106 *np= nil;
108 /* Special "include file" directive. */
109 if (np == names + 2 && strcmp(names[0], "include") == 0) {
110 fclose(hfp);
111 hfp= nil;
112 hosts= nil;
113 if (strlen(names[1]) < sizeof(nexthosts)) {
114 strcpy(nexthosts, names[1]);
115 hosts= nexthosts;
117 continue;
120 /* At least two words, the first of which is an IP address. */
121 if (np < names + 2) continue;
122 if (!inet_aton((char *) names[0], &addr)) continue;
123 host.h_name= (char *) names[1];
125 return &host;
129 /* Rest kept in reserve, we probably never need 'em. */
130 #if XXX
131 struct hostent *gethostbyname(const char *name)
133 struct hostent *he;
134 char **pa;
135 char alias[256];
136 char *domain;
138 sethostent(0);
139 while ((he= gethostent()) != nil) {
140 if (strcasecmp(he->h_name, name) == 0) goto found;
142 domain= strchr(he->h_name, '.');
143 for (pa= he->h_aliases; *pa != nil; pa++) {
144 strcpy(alias, *pa);
145 if (domain != nil && strchr(alias, '.') == nil) {
146 strcat(alias, domain);
148 if (strcasecmp(alias, name) == 0) goto found;
151 found:
152 endhostent();
153 return he;
156 struct hostent *gethostbyaddr(const char *addr, int len, int type)
158 struct hostent *he;
160 sethostent(0);
161 while ((he= gethostent()) != nil) {
162 if (he->h_name[0] == '%') continue;
163 if (type == AF_INET && memcmp(he->h_addr, addr, len) == 0) break;
165 endhostent();
166 return he;
168 #endif