1 /* gethostent() - Interface to /etc/hosts Author: Kees J. Bot
5 /* Prefix the functions defined here with underscores to distinguish them
6 * from the newer replacements in the resolver library.
8 #define sethostent _sethostent
9 #define endhostent _endhostent
10 #define gethostent _gethostent
11 #define gethostbyname _gethostbyname
12 #define gethostbyaddr _gethostbyaddr
15 #include <sys/types.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.) */
38 /* End search and reinitialize. */
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.) */
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. */
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; }
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. */
89 if (lp
== arraylimit(line
)) continue;
92 /* Break the line up in words. */
96 while (isspace(*lp
) && *lp
!= 0) lp
++;
97 if (*lp
== 0 || *lp
== '#') break;
98 if (np
== arraylimit(names
)) break;
100 while (!isspace(*lp
) && *lp
!= 0) lp
++;
105 if (np
== arraylimit(names
)) continue;
108 /* Special "include file" directive. */
109 if (np
== names
+ 2 && strcmp(names
[0], "include") == 0) {
113 if (strlen(names
[1]) < sizeof(nexthosts
)) {
114 strcpy(nexthosts
, names
[1]);
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];
129 /* Rest kept in reserve, we probably never need 'em. */
131 struct hostent
*gethostbyname(const char *name
)
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
++) {
145 if (domain
!= nil
&& strchr(alias
, '.') == nil
) {
146 strcat(alias
, domain
);
148 if (strcasecmp(alias
, name
) == 0) goto found
;
156 struct hostent
*gethostbyaddr(const char *addr
, int len
, int type
)
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;