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

int
main(int argc, char **argv)
{
	const char *node = "pclin281";
	struct addrinfo hints;
	struct addrinfo *res;
	int ret, i;

	struct hostent *he;
	const char *name = "pclin281";
	char **alias;

	char *dst;
	char dst4[INET_ADDRSTRLEN];
	char dst6[INET6_ADDRSTRLEN];

	// Canonical name
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_flags = AI_CANONNAME;
	if ((ret = getaddrinfo(node, NULL, &hints, &res)) != 0) {
		printf("gai canon error: %s\n", gai_strerror(ret));
		return 1;
	}

	i = 0;
	while (res) {
		if (res->ai_addr->sa_family == AF_INET) {
			if ((dst = inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, dst4, INET_ADDRSTRLEN)) == NULL) {
				printf("gai canon inet_ntop AF_INET error");
				return 1;
			}
		} else {
			if ((dst = inet_ntop(AF_INET6, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, dst6, INET6_ADDRSTRLEN)) == NULL) {
				printf("gai canon inet_ntop AF_INET6 error");
				return 1;
			}
		}

		printf("gai canon result %d: %s %s\n", i, res->ai_canonname, dst);
		res = res->ai_next;
		i++;
	}

	// Noncanonical name
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	if ((ret = getaddrinfo(node, NULL, &hints, &res)) != 0) {
		printf("gai error: %s\n", gai_strerror(ret));
		return 1;
	}

	i = 0;
	while (res) {
		if (res->ai_addr->sa_family == AF_INET) {
			if ((dst = inet_ntop(AF_INET, &((struct sockaddr_in *)res->ai_addr)->sin_addr, dst4, INET_ADDRSTRLEN)) == NULL) {
				printf("gai inet_ntop AF_INET error");
				return 1;
			}
		} else {
			if ((dst = inet_ntop(AF_INET6, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, dst6, INET6_ADDRSTRLEN)) == NULL) {
				printf("gai inet_ntop AF_INET6 error");
				return 1;
			}
		}

		printf("gai result %d: %s %s\n", i, res->ai_canonname, dst);
		res = res->ai_next;
		i++;
	}

	// Gethostbyname
	for (i = 0; i < 10; i++) {
		if ((he = gethostbyname(name)) == NULL)
			herror("gethostbyname");

		printf("ghbn result %d h_name: %s\n", i, he->h_name);
		
		alias = he->h_aliases;
		if (*alias == NULL) {
			printf("ghbn result %d h_alias: __NONE__\n", i);
		} else {
			while (*alias) {
				printf("ghbn result %d h_alias: %s\n", i, *alias);
				alias++;
			}
		}
	}

	return 0;
}
