/* wydanie czwarte. kompiluje sie pod FreeBSD. korekta: bajkero */
/* wydanie trzecie. korekta: MatNet. */
/* wydanie drugie, poprawione. korekta: Lam. */
/* wydanie pierwsze. wojtekka. */

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

int main(int argc, char **argv)
{
	struct addrinfo hints, *res = NULL;
	struct sockaddr_in6 sin6;
	char buf[128];
	int gai_err;

	if (argc < 2) {
		fprintf(stderr, "usage: %s host/ipv6\n", argv[0]);
		return 1;
	}

	memset(&sin6, 0, sizeof(sin6));

	if (strchr(argv[1], ':')) {
		sin6.sin6_family = AF_INET6;
		sin6.sin6_port = 0;
#ifdef SIN6_LEN
		sin6.sin6_len = sizeof(sin6);
#endif
		if (!inet_pton(AF_INET6, argv[1], &sin6.sin6_addr)) {
			fprintf(stderr, "%s invalid\n", argv[1]);
			return 1;
		}
		if (!(gai_err = getnameinfo((struct sockaddr*) &sin6, sizeof(sin6), buf, sizeof(buf), NULL, 0, NI_NAMEREQD)))
			printf("%s is %s\n", argv[1], buf);
		else
			printf("%s not found: %s\n", argv[1], gai_strerror( gai_err ));
	} else {
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_INET6;

		if (!getaddrinfo(argv[1], NULL, &hints, &res) && res) {
			if (res->ai_family == AF_INET)
				inet_ntop(AF_INET, &((struct sockaddr_in*)res->ai_addr)->sin_addr, buf, sizeof(buf));
			else
				inet_ntop(AF_INET6, &((struct sockaddr_in6*)res->ai_addr)->sin6_addr, buf, sizeof(buf));

			printf("%s is %s\n", argv[1], buf);

			freeaddrinfo(res);
		} else
			fprintf(stderr, "%s not found\n", argv[1]);
	}


	return 0;
}
