struct hostent * gethostent_r(FILE *hf, struct hostent *hent, char *buf, size_t buflen, int *he) { char *p, *name; char *cp, **q; int af, len; size_t llen, anum; char *aliases[MAXALIASES]; struct in6_addr host_addr; if (hf == NULL) { *he = NETDB_INTERNAL; errno = EINVAL; return NULL; } again: if ((p = fgetln(hf, &llen)) == NULL) { *he = HOST_NOT_FOUND; return NULL; } if (llen < 1) goto again; if (*p == '#') goto again; p[llen] = '\0'; if (!(cp = strpbrk(p, "#\n"))) goto again; *cp = '\0'; if (!(cp = strpbrk(p, " \t"))) goto again; *cp++ = '\0'; if (inet_pton(AF_INET6, p, &host_addr) > 0) { af = AF_INET6; len = NS_IN6ADDRSZ; } else if (inet_pton(AF_INET, p, &host_addr) > 0) { #if 0 res_state res = __res_get_state(); if (res == NULL) return NULL; if (res->options & RES_USE_INET6) { map_v4v6_address(buf, buf); af = AF_INET6; len = NS_IN6ADDRSZ; } else { #endif af = AF_INET; len = NS_INADDRSZ; #if 0 } __res_put_state(res); #endif } else { goto again; } /* if this is not something we're looking for, skip it. */ if (hent->h_addrtype != 0 && hent->h_addrtype != af) goto again; if (hent->h_length != 0 && hent->h_length != len) goto again; while (*cp == ' ' || *cp == '\t') cp++; if ((cp = strpbrk(name = cp, " \t")) != NULL) *cp++ = '\0'; q = aliases; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } if (q >= &aliases[__arraycount(aliases)]) goto nospc; *q++ = cp; if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; } hent->h_length = len; hent->h_addrtype = af; HENT_ARRAY(hent->h_addr_list, 1, buf, buflen); anum = (size_t)(q - aliases); HENT_ARRAY(hent->h_aliases, anum, buf, buflen); HENT_COPY(hent->h_addr_list[0], &host_addr, hent->h_length, buf, buflen); hent->h_addr_list[1] = NULL; HENT_SCOPY(hent->h_name, name, buf, buflen); for (size_t i = 0; i < anum; i++) HENT_SCOPY(hent->h_aliases[i], aliases[i], buf, buflen); hent->h_aliases[anum] = NULL; *he = NETDB_SUCCESS; return hent; nospc: errno = ENOSPC; *he = NETDB_INTERNAL; return NULL; }
static struct hostent * fakeaddr(const char *name, int af, struct net_data *net_data) { struct pvt *pvt; freepvt(net_data); net_data->ho_data = malloc(sizeof (struct pvt)); if (!net_data->ho_data) { errno = ENOMEM; RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); return (NULL); } pvt = net_data->ho_data; #ifndef __bsdi__ /* * Unlike its forebear(inet_aton), our friendly inet_pton() is strict * in its interpretation of its input, and it will only return "1" if * the input string is a formally valid(and thus unambiguous with * respect to host names) internet address specification for this AF. * * This means "telnet 0xdeadbeef" and "telnet 127.1" are dead now. */ if (inet_pton(af, name, pvt->addr) != 1) { #else /* BSDI XXX * We put this back to inet_aton -- we really want the old behavior * Long live 127.1... */ if ((af != AF_INET || inet_aton(name, (struct in_addr *)pvt->addr) != 1) && inet_pton(af, name, pvt->addr) != 1) { #endif RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND); return (NULL); } strncpy(pvt->name, name, NS_MAXDNAME); pvt->name[NS_MAXDNAME] = '\0'; if (af == AF_INET && (net_data->res->options & RES_USE_INET6) != 0U) { map_v4v6_address(pvt->addr, pvt->addr); af = AF_INET6; } pvt->host.h_addrtype = af; switch(af) { case AF_INET: pvt->host.h_length = NS_INADDRSZ; break; case AF_INET6: pvt->host.h_length = NS_IN6ADDRSZ; break; default: errno = EAFNOSUPPORT; RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL); return (NULL); } pvt->host.h_name = pvt->name; pvt->host.h_aliases = pvt->aliases; pvt->aliases[0] = NULL; pvt->addrs[0] = (char *)pvt->addr; pvt->addrs[1] = NULL; pvt->host.h_addr_list = pvt->addrs; RES_SET_H_ERRNO(net_data->res, NETDB_SUCCESS); return (&pvt->host); } #ifdef grot /*%< for future use in gethostbyaddr(), for "SUNSECURITY" */ struct hostent *rhp; char **haddr; u_long old_options; char hname2[MAXDNAME+1]; if (af == AF_INET) { /* * turn off search as the name should be absolute, * 'localhost' should be matched by defnames */ strncpy(hname2, hp->h_name, MAXDNAME); hname2[MAXDNAME] = '\0'; old_options = net_data->res->options; net_data->res->options &= ~RES_DNSRCH; net_data->res->options |= RES_DEFNAMES; if (!(rhp = gethostbyname(hname2))) { net_data->res->options = old_options; RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND); return (NULL); } net_data->res->options = old_options; for (haddr = rhp->h_addr_list; *haddr; haddr++) if (!memcmp(*haddr, addr, INADDRSZ)) break; if (!*haddr) { RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND); return (NULL); } }