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

void wait()
{
	static unsigned char cur='/';
	switch(cur)
	{
		case '-':
			cur = '\\';
			break;
		case '\\':
			cur = '|';
			break;
		case '|':
			cur = '/';
			break;
		case '/':
			cur = '-';
			break;
	}
	printf("\b%c", cur);
	fflush(stdout);
}

void mainloop(int fd, char *s)
{
	struct timeval tv;
	fd_set fds;
	unsigned char buf[6];
	int bytes;
	int x;
	
	tv.tv_sec = 0;
	tv.tv_usec = 0;

	
	printf("Resolving %s  ", s);
	while(1)
	{
		wait();
		FD_ZERO(&fds);
		FD_SET(fd, &fds);
		FD_SET(STDIN_FILENO, &fds);
		x = select(fd+1, &fds, NULL, NULL, &tv);
		if (x)
		{
			bytes=read(fd, buf, 6);
			if (buf[0]=='+')
			{
				printf("\bOK: %d.%d.%d.%d\n", buf[1], buf[2], \
						buf[3], buf[4]);
			}
			else
			{
				printf("\bERR: Host does not exist!\n");
			}
			return;
		}
		usleep(50000);
	}
	return;
}

void dnslookup(int fd, char *s)
{
	struct hostent *addr;
	struct sockaddr_in in;
	unsigned long num;
	unsigned char buf[6];
	
	addr = gethostbyname(s);
	if (!addr)
	{
		sprintf(buf, "-    ");
		write(fd, buf, 6);
		return;
	}
	in.sin_addr = *(struct in_addr*)addr->h_addr;

	num=in.sin_addr.s_addr;

	sprintf(buf, "+%c%c%c%c", (char)num%256, (char)(num/256)%256, \
			(char)(num/65536)%256, (char)(num/16777216)%256);
	write(fd, buf, 6);
}

int main(int argc, char *argv[])
{
	int forkpid;
	int fd[2];

	if (argc != 2)
	{
		printf("Usage: %s <host>\n", argv[0]);
		exit(1);
	}

	if (pipe(fd))
	{
		printf("Cannot create pipe!\n");
		exit(1);
	}
	
	
	forkpid = fork();
	if (forkpid == -1)
	{
		printf("Cannot fork process!\n");
		exit(1);
	}
	if (forkpid != 0)
		mainloop(fd[0], argv[1]);
	else
		dnslookup(fd[1], argv[1]);
	return 0;
}

