/* alookup.c - tool to lookup hosts on an alived server   
   Copyright (C) 2003, Kris Foster <kris@krweb.net>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "alived.h"

void pversion(void);
void usage(void);                       // Explain the command line options
void invalid_switch(char option);       // The user tried something stupid

int 
main(int argc, char *argv[])
{
	int retry;
	int addr_len;
        int server_port=ALIVE_PORT;
        int m_len, a_len;
        int nbytes;
        int sockfd;
        char *server_addr="127.0.0.1";
        time_t l_time;
	struct sockaddr_in l_addr;
	struct sockaddr_in r_addr;
        struct sockaddr_in serv_addr;
        struct in_addr query_addr;
	struct hostent *he;
	struct message s_dgram;
	struct watchlist r_dgram;
        
        m_len=sizeof(struct message);
        a_len=sizeof(struct sockaddr);

	s_dgram.type=htonl(LOOKUP);
	
	if(argc==1) {
		usage();
		exit(1);
 	}

	strcpy(s_dgram.id,argv[1]);  // the host the user wants to lookup

	if(argc==3) {
		server_addr=argv[2];
	}
        
        he=gethostbyname(server_addr);
        if(he==NULL){
                perror("gethostbyname");
                exit(1);
       	}

        sockfd=socket(AF_INET, SOCK_DGRAM, 0);
        if(sockfd==-1){
                perror("socket");
                exit(1);
        }

	fcntl(sockfd, F_SETFL, O_NONBLOCK);

	l_addr.sin_family=AF_INET;
	l_addr.sin_port=htons(0);		// random port
	l_addr.sin_addr.s_addr=INADDR_ANY;	// any source ip
	memset(&(l_addr.sin_zero), '\0', 8);

	if(bind(sockfd, (struct sockaddr *)&l_addr, a_len)==-1) {
		perror("bind");
		exit(1);
	}
	
        serv_addr.sin_family=AF_INET;
 	if(argc==3) {
		// convert string to int
	}
	serv_addr.sin_port=htons(server_port);
        serv_addr.sin_addr = *((struct in_addr *)he->h_addr);
        memset(&(serv_addr.sin_zero), '\0', 8);
	
	addr_len=sizeof(struct sockaddr);

	printf("Server: %s\n",he->h_name);
        
        // We could possibly add support to cycle through a list of servers
	for(retry=0;retry<RETRYLIMIT;retry++) {
		nbytes=sendto(sockfd,&s_dgram,m_len,0,(struct sockaddr *)&serv_addr,a_len);
                if(nbytes==-1) {
                        perror("sendto");
                        exit(1);
                }
 		sleep(ITIMEOUT);	// give the server a moment to think
	
		nbytes=recvfrom(sockfd,&r_dgram,m_len,0,(struct sockaddr *)&r_addr,&addr_len);
                if(nbytes==-1) {
			printf("Query %d timed out\n",retry+1);
			sleep(TIMEOUT);
		} else {
                        break;
		}
	}
	
        if(!strcmp(r_dgram.id,NOTFOUNDCHAR)) {
                printf("%s never contacted this server\n",&s_dgram.id);
        } else {
                printf("Hostname: %s\n", r_dgram.id);
                //char *
                //     inet_ntoa(struct in_addr in);
                query_addr.s_addr=r_dgram.ip_addr;
                printf("Address: %s\n",inet_ntoa(query_addr));
                // last heard at
                l_time=ntohl(r_dgram.last_heard);
                printf("Last contact: %s",ctime(&l_time));
        }
        
        close(sockfd);

        return 0;
}

void 
pversion(void)
{
	printf("alookup version %s\n", VERSION);
}

void 
usage(void)
{
	printf("Usage: alookup hostname [server address] [port]\n");
}



