/* 
  client.ch
  This is a client program which is set up to be run along with server.ch.

  Usage :
      client.ch [-i IP_ADDRESS | -h HOST_NAME] [-p PORT_NUMBER]
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define PROTOPORT 5139    /* default protocol port number */
char localhost[]= "localhost"; /* default host name */

/* Usage will be display if there is any incorrect option */
char usage[]= "\nThis is a client program which is set up to be run along with server.ch.\n\nUsage :\n      client.ch [-i IP_ADDRESS | -h HOST_NAME] [-p PORT_NUMBER]\n\n      IP_ADDRESS  : IP address of the machine on which server.ch is running.\n      HOST_NAME   : hostname of the machine on which server.ch is running.\n      PORT_NUMBER : TCP port number used by server.ch\n\nFor example :\n      client.ch\n      client.ch -i 12.34.56.78\n      client.ch -h myhost\n      client.ch -p 6000\n      client.ch -i 12.34.56.78 -p 6000\n      client.ch -h myhost -p 6000\n\nThe default optional values :\n      HOST_NAME   : localhost\n      PORT_NUMBER : 5139\n\n";  

int main(int argc,char *argv[]) {
    struct hostent *ptrh;      /* pointer to a host table entry     */
    struct protoent *ptrp;     /* pointer to a protocol table entry */
    struct sockaddr_in sad;    /* structure to hold an IP address   */
    int    sd;                 /* socket descriptor                 */
    int port;                  /* protocol port number              */
    char *host;                /* pointer to host name              */
    char buf[1000];            /* buffer for data from the server   */

    setbuf(stdout,NULL);       /* turn off the out buffer           */
    memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
    sad.sin_family=AF_INET;             /* set family to internet   */
 
    /* set default optional values */
    port=PROTOPORT;
    host=localhost;
    sad.sin_addr.s_addr = (unsigned int)-1;

    /* get the user-defined optional values */
    if(argc > 1) {
      for(; *argv != NULL; argv++) {
         /* get ip address */ 
         if(strcmp(*argv, "-i") == 0 || strcmp(*argv, "-I") == 0) {
           argv++;
           sad.sin_addr.s_addr = inet_addr(*argv); 
         }
         /* get tcp port number */
         if(strcmp(*argv, "-p") == 0 || strcmp(*argv, "-P") == 0) {
           argv++;
           port = atoi(*argv); 
         }
         /* get hostname */
         if(strcmp(*argv, "-h") == 0 || strcmp(*argv, "-H") == 0) {
           argv++;
           host = *argv;
         }

      }
    }  

    /* convert port */ 
    if(port>0)
        sad.sin_port=htons((u_short)port);
    else {
        fprintf(stderr,"\nError : bad port number %s\n",argv[1]);
        printf("%s", usage);
        exit(1);
    }
  
    /* convert IP address. */
    if( sad.sin_addr.s_addr == (unsigned int)-1) {
       ptrh=gethostbyname(host);
       if(((char *)ptrh)==NULL) {
          fprintf(stderr,"\nError : invalid host: %s \n",host);
          printf("%s", usage);
          exit(1);
       }
       memcpy(&sad.sin_addr,ptrh->h_addr,ptrh->h_length);
    }

    /* map TCP transport protocol name to protocol number. */
    if(((int)(ptrp=getprotobyname("tcp")))==0) {
        fprintf(stderr,"\nError : cannot map \"tcp\" to protocol number");
        printf("%s", usage);
        exit(1);
    }
  
    /* creat a socket */
    sd=socket(PF_INET,SOCK_STREAM,ptrp->p_proto);
    if(sd<0) {
        fprintf(stderr,"\nError : socket creation failed \n");
        printf("%s", usage);
        exit(1);
    }
  
    /* connect the socket to the specified  server. */
    if(connect(sd,(struct sockaddr *)&sad,sizeof(sad))!=0) {
       fprintf(stderr,"\nError : connect failed\n");
       printf("%s", usage);
       close(sd);
       exit(1);
    }

    /* send a tcp package tp server */
    sprintf(buf,"From the Client");
    send(sd,buf,strlen(buf),0);

    /* receive a tcp package from server */
    recv(sd,buf,sizeof(buf),0);
    printf("Data received: %s\n", buf); 

    printf("Connection to server closed\n"); 
    close(sd);
    exit(0);
} 
