#include "udpwhois.h"

/**
 * File Name: udpwhois_client.cpp
 * Author   : Edison Chindrawaly
 * Course   : CSCI 4330TCP/IP
 * Descp    : client/server using UDP protocol to find out
 *            in which CSP server a certain user login.
 */
void main(int argc, char *argv[])
{
 struct sockaddr_in client,server;
 struct hostent *host_entry;

 if(argc != 3)
 {
  cout<<"Usage: ./program_name <username> <port number>"<<endl;
  exit(0);
 }
 char* username = argv[1];
 int port = atoi(argv[2]);
 unsigned int server_size = sizeof(client);

 int sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
 verify(sock,sock,socket_flag);


 client.sin_family = AF_INET;
 client.sin_port = htons(0);
 client.sin_addr.s_addr=htonl(INADDR_ANY);


 verify(sock,
        bind(sock,(struct sockaddr *)&client,sizeof(client)),
        bind_flag);

 char arrayOfCsp[10][19] = { "csp01.csci.unt.edu",
                             "csp02.csci.unt.edu",
                             "csp03.csci.unt.edu",
                             "csp04.csci.unt.edu",
                             "csp05.csci.unt.edu",
                             "csp06.csci.unt.edu",
                             "csp07.csci.unt.edu",
                             "csp08.csci.unt.edu",
                             "csp09.csci.unt.edu",
                             "csp10.csci.unt.edu" };

 MESSAGE msg;
 msg.command = 1;
 int foundArray[10] = {0,0,0,0,0,0,0,0,0,0};
 unsigned int none = 0;

 for(int i=0; i < 10; i++)
 {
  if((host_entry=gethostbyname(arrayOfCsp[i]))==NULL)
    perror("ERROR: gethostbyname has failed\n");
 
  server.sin_family = AF_INET;
  server.sin_port = htons((unsigned short)port);
  server.sin_addr.s_addr = *((unsigned long *)host_entry->h_addr);

  strcpy(msg.msg,username);
  verify(sock,
         sendto(sock, &msg, sizeof(msg),0,
               (struct sockaddr *)&server, sizeof(server)),
         send_flag);

  verify(sock,
         recvfrom(sock, &msg, sizeof(msg),0,
                 (struct sockaddr *)&client, &none),
         receive_flag);
  if(strcmp(msg.msg,"FOUND") == 0)
    foundArray[i] = 1;
 }
 closeConnection(sock);
 cout<<"User "<<username<<" login to ";
 for(int i=0; i<10; i++)
   if(foundArray[i] == 1)
     cout<<arrayOfCsp[i]<<", "; 
 cout<<" no other csp server"<<endl;
}


/**
 * verify's method is to verify the success of the operation.
 * if the operation fails, it will terminate the whole program.
 * @param  int sockfd contains socket descriptor if available
 *         int byte contains the byte receives from the operation
 *         int flag contains the description of the flag
 * @return none
 */
void verify(int sockfd, int byte, int flag)
{
 switch(flag)
 {
  case 0:if(byte<0)
         {
           perror("ERROR: socket has failed\n");
           exit(0);
         }
         break;
  case 1:if(byte<0)
         {
           perror("ERROR: bind has failed\n");
           closeConnection(sockfd);
           exit(0);
         }
         break;
  case 2:if(byte<0)
         {
           perror("ERROR: listen has failed\n");
           closeConnection(sockfd);
           exit(0);
         }
         break;
  case 3:if(byte<0)
         {
           perror("ERROR: accept has failed\n");
           closeConnection(sockfd);
           exit(0);
         }
         break;
  case 4:if(byte<0)
         {
           perror("ERROR: send has failed\n");
           closeConnection(sockfd);
           exit(0);
         }
         break;
  case 5:if(byte<0)
         {
           perror("ERROR: receive has failed\n");
           closeConnection(sockfd);
           exit(0);
         }
         break;
  case 6:if(byte<0)
         {
           perror("ERROR: pipe has failed\n");
           exit(0);
         }
         break;
  case 7:if(byte<0)
         {
           perror("ERROR: write has failed\n");
           exit(0);
         }
         break;
  case 8:if(byte<0)
         {
           perror("ERROR: read has failed\n");
           exit(0);
         }
         break;
  case 9:if(byte<0)
         {
           perror("ERROR: select has failed\n");
           exit(0);
         }
  default: break;
 }
}

/**
 * closeConnection's method is to close the socket
 * descriptor that contains the connection of
 * the client/server's model
 * @param  int sockfd contains socket descriptor
 * @return none
 */
void closeConnection(int sockfd)
{
 close(sockfd);
}
 

1