#include "udpwhois.h"

/**
 * File Name : udpwhois_server.cpp
 * Author    : Edison Chindrawaly
 * Course    : CSCI 4330TCP/IP
 * Descp     : Checking the existance of the certain user
 *             in the server - based on the request of
 *             udpwhois_client
 */

int openConnection(int);
int performCheck(char *);

void main(int argc, char *argv[])
{
 int n_size;
 int port = 0;
 struct sockaddr_in clientAdd;
 unsigned int client_size = sizeof(clientAdd);
 char errorMSG1[MAXSIZE] = "ERROR: command exceed MAX";
 char errorMSG2[MAXSIZE] = "ERROR: command contains NULL";
 char foundMSG[6]  = "FOUND";
 MESSAGE msg;

 if(argc != 2)
 {
  cout<<"Usage: ./udpwhois_server <UDP SERVER PORT>\n";
  exit(1);
 }
 else
   port = atoi(argv[1]);
  
 int socketfd = openConnection(port);
 
 n_size = recvfrom(socketfd, &msg, sizeof(msg),0,
                  (struct sockaddr *)&clientAdd,
                  &client_size);
 verify(socketfd, n_size, receive_flag);
 cout<<"Client ["<<inet_ntoa(clientAdd.sin_addr)<<"] ";
 int found;
 if(msg.command == 1)
 {
   cout<<" commands to find user: "<<msg.msg<<endl;
   if(strlen(msg.msg) > MAXSIZE)
   {
    strcpy(msg.msg,errorMSG1);
    msg.command = 2;
   }
   else if(msg.msg == NULL)
   {
    strcpy(msg.msg,errorMSG2);
    msg.command = 2;
   }
   else
   {
    found = performCheck(msg.msg);
    if(found == 1)
    {
     cout<<"user "<<msg.msg<<" logins into the current server"<<endl;
     msg.command = 1;
     strcpy(msg.msg,foundMSG);
    }
    else
     cout<<"user "<<msg.msg<<" does not login to the current server"<<endl;
   }
 }
 else
   cout<<" has no command"<<endl;

 if(msg.command > 0)
 {
  n_size = sendto(socketfd, &msg, sizeof(msg),0,
                 (struct sockaddr *)&clientAdd,
                 sizeof(clientAdd));
  verify(socketfd, n_size, send_flag);
 }
 closeConnection(socketfd);
}


/**
 * performCheck(): To check the certain user in the system.
 *                 It will return 0 if not found. else 1
 * @param  char* input - the user to search for
 * @return int 1 if user is found, else 0
 */
int performCheck(char* input)
{
 FILE *fpin;
 char buffer[MAXSIZE];
 char cmd[2] = "w";
 if((fpin = popen(cmd,"r")) == NULL)
   return 0;
 while(fgets(buffer, MAXSIZE, fpin)!=NULL)
   if(strstr(buffer,input) != NULL)
     return 1;
 return 0;
}

/**
 * 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);
}



/**
 * openConnection's method is to establish connection
 * between the client and server. This is for Server used.
 * @param  int PORT contains predefine port number
 * @return sockfd if flag == 1 else connfd is return
 */
int openConnection(int PORT)
{
 int servsize;
 int yes = 1;
 int sockfd,connfd,clientsize;
 struct sockaddr_in my_add;

 sockfd = socket(PF_INET, SOCK_DGRAM,IPPROTO_UDP);
 verify(0,sockfd,socket_flag);

 memset(&my_add,0,sizeof(my_add));
 my_add.sin_family = AF_INET;
 my_add.sin_port = htons(PORT);
 my_add.sin_addr.s_addr = INADDR_ANY;
 
 verify(sockfd,       
        bind(sockfd,(struct sockaddr *)&my_add,
        sizeof(struct sockaddr)),
        bind_flag);

 return sockfd;
}

 

1