void ReadHostFile (const char *fname) { if (!fname || !*fname) return; hostFname = strdup (fname); if (!hostFname) return; sethostent (1); if (!hostFile) return; while (1) { struct _hostent h; if (!_gethostent(&h)) break; if (!tree_insert(&host_root, (void*)&h, sizeof(h), (CmpFunc)host_cmp_name)) { outsnl (_LANG("Hostfile too big!\7")); break; } } atexit (endhostent); }
struct hostent *gethostent (void) { struct _hostent h; if (_gethostent(&h)) return FillHostEnt (&h); return (NULL); }
static int name2ip(ipaddr_t *pip, const char *name, ipaddr_t ifip) { /* Translate a name to an IP address, preferably from the hosts file, * but also from the DNS if being a server. Prefer the address closest * to the interface with IP address 'ifip' if there are choices.. */ extern struct hostent *_gethostent(void); /* File reading versions. */ extern void _endhostent(void); struct hostent *he; size_t len= strlen(name); u32_t d, distance= -1; ipaddr_t ip; int i; char *hn; /* Already an IP address? */ if (inet_aton(name, (struct in_addr *)pip)) return 1; /* In the hosts file? */ while ((he= _gethostent()) != nil) { hn= he->h_name; i= -1; do { if (strncasecmp(name, hn, len) == 0 && (hn[len] == 0 || hn[len] == '.') ) { memcpy(&ip, he->h_addr, sizeof(ip)); d= ntohl(ip) ^ ntohl(ifip); if (d < distance) { *pip= ip; distance= d; } break; } } while ((hn= he->h_aliases[++i]) != nil); } _endhostent(); if (distance < -1) return 1; /* Nothing? Try the real DNS if being a server. */ if (serving) { if ((he= gethostbyname(name)) != nil && he->h_addrtype == AF_INET) { /* Select the address closest to 'ifip'. */ for (i= 0; he->h_addr_list[i] != nil; i++) { memcpy(&ip, he->h_addr_list[i], sizeof(ip)); d= ntohl(ip) ^ ntohl(ifip); if (d < distance) { *pip= ip; distance= d; } } return 1; } } return 0; }
static char *ip2name(ipaddr_t ip) { /* Translate an IP address to a name, etc, etc. */ extern struct hostent *_gethostent(void); /* File reading versions. */ extern void _endhostent(void); struct hostent *he; /* In the hosts file? */ while ((he= _gethostent()) != nil) { if (memcmp(he->h_addr, &ip, sizeof(ip)) == 0) break; } _endhostent(); /* Nothing? Try the real DNS if being a server. */ if (he == nil && serving) { he= gethostbyaddr((char *) &ip, sizeof(ip), AF_INET); } return he != nil ? he->h_name : nil; }