/*This program provide common functions for client, dispatcher and server.*/

#include "service.h"

/* A common functions called by both client and server to connect to remote.
   i.e. server connects dispatcher, client connects server.*/ 
int connect_remote(char *dest,int port,int *sock,struct sockaddr_in *serv_addr)
{
  /*struct hostent *server;*/
 int status=0;  /*to contain the value to return.*/
 /*int yes=1;*/
 struct hostent *server;

 /*if sock fails, return 1.*/
 if ( (*sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
   {
     perror("socket");
     status++;
     return status;
   }
 
 /*set up the destination address sockaddr_in structure.*/
 if((server = gethostbyname(dest))==NULL)
          {
           printf("\n");
           perror("gethostbyname");
           status++;
           return status;
	  }
 memset(serv_addr,0,sizeof(struct sockaddr_in));
 serv_addr->sin_family = AF_INET;
 serv_addr->sin_addr.s_addr=((struct in_addr *)server->h_addr)->s_addr;
 serv_addr->sin_port = htons(port);

 /*if connect fails, return 1.*/
 if (connect(*sock,(struct sockaddr *)serv_addr,sizeof(struct sockaddr)) ==-1) 
          {
           printf("\n");
           perror("connect");
           status++;
           return status;
	  }
  if(status==0) printf("Done!\n");
  return status;
}


/*A common function called by both dispatcher and server.It first create a 
  socktet, then bind the socket with a port, and listen on this port.If fails,
  return 1,otherwise return 0.*/
int bind_remote(int port,int *sockfd,struct sockaddr_in *my_addr)
    { 
      int status=0; /*To contain the value to return.*/
      int yes=1;

      /*if sock fails, status will be 1, and return it.*/
      if ( (*sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
	  perror("socket");
          status++;
	  return status;
	}
      
      /*set up the my_addr sockaddr_in structure.*/
      my_addr->sin_family = AF_INET;    
      my_addr->sin_addr.s_addr = htonl(INADDR_ANY); 
      my_addr->sin_port = htons(port); 
      memset(&(my_addr->sin_zero), '\0', 8); 

      /*make the socket(port) re_usable for bind() */
      if (setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR,(const void *) &yes, sizeof(int))==-1)
	{
	  perror("setsockopt");
          status++;
	  return status;
	  
	}
  
      /*associate the socket with a port on the machine, if fails, status
       will be set to 1.*/
      if ( bind (*sockfd, (struct sockaddr *) my_addr,
		 sizeof(struct sockaddr)) < 0)
	{
	  perror("bind");
          status++;
	  return status;
	  
	}

      /*listen on this port, if listen fails, status will be set to 1, and
        return it.*/
      if (listen(*sockfd, MAX_QUEUE) < 0)
	{
	  perror("listen");
          status++;
	  return status;
	}
     return status;
    }