static int add_hostent (int port, int protocol, int socktype, struct addrinfo ***current, int (*func)(struct addrinfo *, void *data, int port), struct hostent *he, int *flags) { int ret; char *canonname = NULL; char **h; if (*flags & AI_CANONNAME) { struct hostent *he2 = NULL; const char *tmp_canon; tmp_canon = hostent_find_fqdn (he); if (strchr (tmp_canon, '.') == NULL) { int error; he2 = getipnodebyaddr (he->h_addr_list[0], he->h_length, he->h_addrtype, &error); if (he2 != NULL) { const char *tmp = hostent_find_fqdn (he2); if (strchr (tmp, '.') != NULL) tmp_canon = tmp; } } canonname = strdup (tmp_canon); if (he2 != NULL) freehostent (he2); if (canonname == NULL) return EAI_MEMORY; } for (h = he->h_addr_list; *h != NULL; ++h) { ret = add_one (port, protocol, socktype, current, func, *h, canonname); if (ret) return ret; if (*flags & AI_CANONNAME) { *flags &= ~AI_CANONNAME; canonname = NULL; } } return 0; }
static int doit (int af, const void *addr, size_t addrlen, int port, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { if (host != NULL) { if (flags & NI_NUMERICHOST) { if (inet_ntop (af, addr, host, hostlen) == NULL) return EAI_SYSTEM; } else { struct hostent *he = gethostbyaddr (addr, addrlen, af); if (he != NULL) { strlcpy (host, hostent_find_fqdn(he), hostlen); if (flags & NI_NOFQDN) { char *dot = strchr (host, '.'); if (dot != NULL) *dot = '\0'; } } else if (flags & NI_NAMEREQD) { return EAI_NONAME; } else if (inet_ntop (af, addr, host, hostlen) == NULL) return EAI_SYSTEM; } } if (serv != NULL) { if (flags & NI_NUMERICSERV) { snprintf (serv, servlen, "%u", ntohs(port)); } else { const char *proto = "tcp"; struct servent *se; if (flags & NI_DGRAM) proto = "udp"; se = getservbyport (port, proto); if (se == NULL) { snprintf (serv, servlen, "%u", ntohs(port)); } else { strlcpy (serv, se->s_name, servlen); } } } return 0; }