
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>		/* inet_ntop */
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>

#include "gai.h"

/*
 * Handle either an IPv4 or an IPv6 address and port.
 */

int gn_ipv46(char *host, size_t hostlen, char *serv, size_t servlen, void *aptr, size_t alen, int family, int port, int flags)
{
    char *ptr;
    struct hostent *hptr;
    struct servent *sptr;

    if (hostlen > 0) {
	if (flags & NI_NUMERICHOST) {
	    if (inet_ntop(family, aptr, host, hostlen) == NULL)
		return (1);
	} else {
	    hptr = gethostbyaddr(aptr, alen, family);
	    if (hptr != NULL && hptr->h_name != NULL) {
		if (flags & NI_NOFQDN) {
		    if ((ptr = strchr(hptr->h_name, '.')) != NULL)
			*ptr = 0;	/* overwrite first dot */
		}
		snprintf(host, hostlen, "%s", hptr->h_name);
	    } else {
		if (flags & NI_NAMEREQD)
		    return (1);
		if (inet_ntop(family, aptr, host, hostlen) == NULL)
		    return (1);
	    }
	}
    }

    if (servlen > 0) {
	if (flags & NI_NUMERICSERV) {
	    snprintf(serv, servlen, "%d", ntohs(port));
	} else {
	    sptr = getservbyport(port, (flags & NI_DGRAM) ? "udp" : NULL);
	    if (sptr != NULL && sptr->s_name != NULL)
		snprintf(serv, servlen, "%s", sptr->s_name);
	    else
		snprintf(serv, servlen, "%d", ntohs(port));
	}
    }
    return (0);
}
