/*
 *       _ _            _
 *      | (_)          | |
 *   ___| |_  ___ _ __ | |_
 *  / __| | |/ _ \ '_ \| __|
 * | (__| | |  __/ | | | |_
 *  \___|_|_|\___|_| |_|\__|
 *
 * Auteurs : Aymeric
 *			 Samira
 * Date    : 25/11/2004
 * Fichier : client.c
 * Détails : client qui fait une requete vers un serveur de surnom
 * 			 Pour le lancer : ./client <host_serveur> <port_serveur>
 *
 */

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

/*
 * Variables statiques globales
 */
#define TAILLE_TYPE 3			// d'après la RFC, taille de 3 (ASK,RES,ERR)
#define TAILLE_SURNOM 50		// d'après la RFC, taille de 50
#define TAILLE_ETUDIANT 50		// d'après la RFC, taille de 50
#define DEBUG 0					// si un 1, on a un affichage qui permet de débugguer

#define SIZEBUF 512

/*-----------------------------------------------------------------------*/
ssize_t ecris( int  soq, char *message)
/*
 * Envoie un mot passe en parametre a la connexion courante (donnee en parametre)
 *
 * arguments :
 *	int soq : identifiant de la socket
 *	char * message : le message a envoyer
 *
 * retourne :
 *	ssize_t le nombre de caractere envoye
 */
{
    ssize_t w;

    /*
     * Envoie le mot a la connexion identifie par soq
     * Si w < 0, alors il y a un probleme
     */
    if ( 0 > (w = write(soq,message,strlen(message))) )
	    printf("Fin premature du serveur\n");
    printf("--> J'ecris : %s\n",message);

    return w;
}

/*-----------------------------------------------------------------------*/
ssize_t lis(int soq, char *message)
{
 /*
  * Lis un message sur la connexion courante (donnee en parametre)
  *
  * arguments :
  *	int soq : identifiant de la socket
  *	char * message : le message qui est lu
  *
  * retourne :
  *	ssize_t le nombre de caractere lu
 */
  ssize_t w;

  /*
   * lis le mot a la connexion identifie par soq
   * Si w < 0, alors il y a un probleme
   */

  bzero(message,SIZEBUF-1);

  if ( 0 > (w = read(soq,message,SIZEBUF - 1)) )
    printf("Erreur lecture serveur\n");

  printf("--> Je lis : %s\n",message);

  return w;
}

/*-----------------------------------------------------------------------*/

int main( int argc, char *argv[] )
{
	int soquette;
	struct sockaddr_in config_soquette;
	struct hostent *info_serveur;
	char buf[TAILLE_ETUDIANT];
	char type[TAILLE_TYPE];
	int source;
	char etudiant[TAILLE_ETUDIANT];
	char surnom[TAILLE_SURNOM];
	char *message;
	message=(char *)calloc(sizeof(char),SIZEBUF);

	if (argc != 3)
	{
		fprintf(stderr,"Usage : client <serveur> <num de port>\n");
		exit(17);
	}


	/*
	 * On verifie l'host du serveur
	 */
	if ( (info_serveur = gethostbyname( argv[1] )) == (struct hostent *)NULL )
	{
	    fprintf( stderr, "%s: unknown host: %s\n",argv[0], argv[1] );
	    exit(__LINE__);
	}


	/*
	 * Creation de la socket
	 */
	if ( (soquette = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
	    perror(argv[0]);


	/*
	 *  Configuration de la connexion
	 */
	config_soquette.sin_family = AF_INET;
	(void) bcopy( (char *)info_serveur->h_addr,
		      (char *) &config_soquette.sin_addr,
		      info_serveur->h_length );
	config_soquette.sin_port = htons(atoi(argv[2]));

	/*
	 * Connexion au serveur
	 */
	if ( connect( soquette, (struct sockaddr *) &config_soquette,
		      sizeof config_soquette ) < 0 )
	{
	    perror(argv[0]);
	    exit(__LINE__);
	}

	/*
	 * On entre l'etudiant dont on cherche le surnom
	 */
	printf("Nom de l'etudiant : ");
	scanf("%s", buf);

	/*
	* On forme la requete
	*/
	sprintf(message,"ASK\t0\t%s\t ",buf);

	/*
	* On envoie au serveur la trame
	*/
	ecris(soquette,message);

	/*
	* On lit sa reponse
	*/
	lis(soquette,message);

	/*
	* On vide les variables
	*/
	bzero(type,sizeof(type));
	bzero(etudiant,sizeof(etudiant));
	bzero(surnom,sizeof(surnom));

	/*
	* On répartit notre message dans les diverses variables
	*/
	sscanf(message,"%s\t%d\t%s\%s",type,&source,etudiant,surnom);

	/*
	* Si le type est ERR, cela signifie qu'aucun surnom n'a ete trouve
	*/
	if (!strcmp(type,"ERR")) printf("Etudiant non trouve\n");
	else printf("Etudiant trouve : %s\n",surnom);

	/*
	* Fermeture de la socket
	*/
	if (DEBUG) printf("Je ferme la soquette\n");

	shutdown(soquette, 2);
	close(soquette);

	return 0;
}

