Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

TRANSFERT DE FICHIER VIA LE PROTOCOL TCP/IP


Information sur la source

Catégorie :Réseaux & Internet Classé sous : transfertdefichier, tcpip, réseaux, linux, abdellah Niveau : Expert Date de création : 09/07/2006 Date de mise à jour : 19/07/2006 21:47:19 Vu / téléchargé: 9 611 / 829

Note :
8,43 / 10 - par 7 personnes
8,43 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (15)
Ajouter un commentaire et/ou une note

Description

Ce programme permet le transfert de fichier et la recherche d'une chaine de caractere dans un fichier a distance en utilisant le protocol TCP/IP
 

Source

  • //////////////////////////////////////////////////////////////////////
  • // EL Antri Abdellah //
  • // @-MAIL: El_EMIR_2002@YAHOO.FR //
  • // Universite DJILLALI LIABES SIDI BEL ABBES //
  • // Departement d'informatique //
  • //////////////////////////////////////////////////////////////////////
  • /**************************************************************************/
  • /* Rmarque importante */
  • /* Le serveur créé des fichiers log pour chaque client et un historique */
  • /* des connexions directement dans la racine / par consequent il faut */
  • /* ilo faut avoir les privileges root */
  • /**************************************************************************/
  • //////////////////////////////////////////////////////////////////////////////////////////////
  • // CODE DU SERVEUR //
  • //////////////////////////////////////////////////////////////////////////////////////////////
  • /* Marche sous linux/unix */
  • /* Compilation: cc ftcps.c -o serveur -lpthreqd */
  • /* Execution: ./serveur 1200 */
  • #include <time.h>
  • #include <arpa/inet.h>
  • #include <netdb.h>
  • #include <dirent.h>
  • #include <sys/stat.h>
  • #include <sys/socket.h>
  • #include <sys/types.h>
  • #include <string.h>
  • #include <unistd.h>
  • #include <stdio.h>
  • #define vrai 1
  • #define faux 0
  • // Cette constante permet de specifie la longueur
  • // maximal d'un chemin specifiant un repertoire
  • #define MAX_REP_CHEMIN 2048
  • // Cette constante desgine le nombre de thread autorise a cree
  • #define MAX_THREAD 4
  • // Ddefinie la long maximal du buffer
  • #define MAX_BUF 2048
  • // Structure specaile pour envoyer l'adresse du client
  • // et le descripteur de socket
  • typedef struct comp{int desc; struct sockaddr_in addr;}comp;
  • // Declaraation des variables globales utilise
  • int num_libre;
  • // Tableau d'identificateur
  • pthread_t th_id[MAX_THREAD];
  • // Tableau pour indique les identificateur deja pris
  • int th_occupe [MAX_THREAD];
  • // Fichier contenant l'historique des connexions et des dmandes de connexion
  • FILE *hist;
  • // Declaration des fonctions et procedures
  • // utiliser par notre serveur
  • void section_critique(FILE *);
  • int cree_socket(int, FILE * );
  • char * cherche_fichier(char *, FILE *);
  • void * th_trait(void *);
  • // Procedure principale
  • int main (int argc , char ** argv)
  • {
  • // Descripteur du serveur
  • int serveur;
  • // Nouveau descripteur retourne par accept
  • int nouv_sock;
  • // Adresse du client
  • // Utilise par recvfrom pour recevoir les
  • // informations du client qui a envoye une
  • // demande de connexion
  • struct sockaddr_in client;
  • // Longueur de la structure utilise par client
  • int long_client;
  • // Pour le parcour du tabbleau des identificateurs des thread
  • int i;
  • // utilise pour guarder la Valeur de retour de recvfrom
  • int recue;
  • // Utiliser pour guarder la valeur de retour de sendto
  • int envoye;
  • // Utilise pour la lecture de la demande de connexion
  • char *buf;
  • int long_buf;
  • // Pour lire la date
  • time_t temp;
  • comp special;
  • system("clear");
  • printf("\n Arguments de la ligne de commande ... ");
  • if (argc != 2)
  • {
  • printf(" [FAILED]");
  • printf("\n Usage: serveur num_proto\n");
  • exit(1);
  • }
  • printf(" [OK]");
  • // Creation du fichier historique
  • printf("\n Creation du fichier historique ... ");
  • hist = fopen("historique","w+");
  • if(hist == NULL)
  • {
  • printf(" [FAILED]");
  • perror("Cause");
  • exit(1);
  • }
  • printf(" [OK]");
  • time(&temp);
  • fprintf(hist," -------------------------------------------------\n");
  • fprintf(hist,"| Ce fichier contient l'historique des connexions |\n");
  • fprintf(hist," -------------------------------------------------\n");
  • fprintf(hist," Date de creation: %s \n ", ctime(&temp) );
  • // Initialisation du buffer
  • // On va essayer d'alloue MAX_BUF octet
  • printf("\n Allocation du buffer ... ");
  • fprintf(hist, "\n Allocation du buffer ... ");
  • buf = (char *)malloc(MAX_BUF);
  • if(buf == NULL)
  • {
  • printf("\n Impossible d'alloue de l'espace pour le buffer");
  • // Sans le buffer on ne peut rien faire
  • exit(1);
  • }
  • printf(" [OK]");
  • fprintf(hist, " [OK]");
  • // Initialisation du tableau des threads
  • printf("\n Initialisation du tableau d'id de thread ... ");
  • fprintf(hist, "\n Initialisation du tableau d'id de thread ... ");
  • for (i = 0; i < 4; i++)
  • {
  • th_occupe[i] = -1;
  • }
  • printf(" [OK]");
  • fprintf(hist, " [OK]");
  • // Initialisation num_libre a 0
  • num_libre = 0;
  • // creation du socket
  • fprintf(hist, "\n Creation de socket sur le port %d... ",atoi(argv[1]));
  • printf("\n Creation de socket sur le port %d... ",atoi(argv[1]));
  • serveur = cree_socket(atoi(argv[1]),hist);
  • if(serveur == -1)
  • {
  • printf(" [FAILED]\n");
  • exit(1);
  • }
  • printf(" [OK]\n");
  • fprintf(hist, " Fixer la file d'attente par 5 ... ");
  • printf(" Fixer la file d'attente par 5 ... ");
  • if(listen(serveur, 5) == -1)
  • {
  • printf(" [FAILED]\n");
  • fprintf(hist, " [FAILED]\n");
  • perror("Cause");
  • exit(1);
  • }
  • printf(" [OK]\n");
  • fprintf(hist, " [OK]\n");
  • printf("\n \t Le serveur va entre dans une boucle infini \n");
  • printf(" \t ========================================= ");
  • freopen("/historique","a+",hist);
  • ////////////////////////////////////////////////////////////
  • // Boucle de gestion des connexions //
  • ///////////////////////////////////////////////////////////
  • while(vrai)
  • {
  • fflush(stdout);//vidage de la sortie standard
  • printf("\n \t Attente des demandes de connexion ");
  • printf("\n");
  • // Le serveur attend une demande de connexion
  • fprintf(hist, "\n Attente de demande de connexion ... ");
  • long_client = sizeof(client);
  • nouv_sock = accept(serveur,(struct sockaddr *) &client,&long_client);
  • if(nouv_sock < 0)
  • {
  • fprintf(hist, " [FAILED]\n");
  • perror("Cause");
  • continue ; // On neglige la requete
  • }
  • fprintf(hist, " [OK]");
  • // On doit recupere les informations du client
  • // qui a demande une connexion
  • printf("\n %s:%u demande la connexion au serveur ...",
  • inet_ntoa(client.sin_addr),ntohs(client.sin_port));
  • fprintf(hist, "\n Une demande de connexion est recue:\n");
  • fprintf(hist, " _==================================_\n");
  • fprintf(hist, "\t * Famille du Socket client: %x\n", ntohs(client.sin_family));
  • fprintf(hist, "\t * Port client: %u\n", ntohs(client.sin_port));
  • fprintf(hist, "\t * IP client: %s\n", inet_ntoa(client.sin_addr));
  • if(num_libre > 3)
  • {
  • strcpy(buf,"NO");
  • long_buf = strlen("NO") + 1;
  • fprintf(hist, "\n Le serveur va envoye un refus de connexion ...");
  • envoye =
  • send(nouv_sock , buf , long_buf , 0);
  • if(envoye < 0)
  • {
  • fprintf(hist, " [FAILED]\n");
  • perror("Cause");
  • continue ;
  • }
  • printf(" [OK]\n");
  • printf("\n Connexion du %s:%u refuse: depacement de capacite \n",
  • inet_ntoa(client.sin_addr),ntohs(client.sin_port));
  • fprintf(hist, " [OK]\n");
  • fprintf(hist,"\n|**************************************************|");
  • fprintf(hist,"\n| DEPACEMENT DE CAPACITE DU SERVEUR |");
  • fprintf(hist, "\n| Connexion du client %s refuse |",
  • inet_ntoa(client.sin_addr));
  • fprintf(hist,"\n|**************************************************|");
  • }
  • else
  • {
  • strcpy(buf,"OK");
  • long_buf = strlen("OK") + 1;
  • fprintf(hist, " Le serveur envoi une acceptation de connexion ... ");
  • envoye =
  • send(nouv_sock,buf,long_buf,0);
  • if(envoye < 0)
  • {
  • fprintf(hist," [FAILED]\n");
  • perror("Cause");
  • continue;
  • }
  • fprintf(hist, " [OK]\n");
  • num_libre ++;
  • // On cherche un identificateur libre
  • for(i = 0; i < 4; i++)
  • if(th_occupe[i] == -1)
  • {
  • // La structure special contient le nom de fichier
  • // la chaine a recherche
  • // et l'adresse du client
  • // creation du thread associe au client
  • fprintf(hist, "\n Creation de thread ... ");
  • special.addr = client;
  • special.desc = nouv_sock;
  • if(
  • pthread_create(&th_id[i],
  • NULL,(void *) th_trait,
  • (void *)&special) != 0
  • )
  • {
  • fprintf(hist, " [FAILED]\n");
  • exit(1);
  • }
  • th_occupe[i] = th_id[i];
  • break;
  • }
  • }
  • freopen("/historique","a+",hist);
  • }// while(true)
  • }
  • // Thread dedie pour la recherche de fichier
  • // Et la recherche des motifs dans un fichier
  • void * th_trait(void *special)
  • {
  • // Descipteur de la socket bidirectionnelle
  • // retourne par accept
  • int serveur;
  • // Descripteur de fichier
  • // utilise par fopen pour la lecture de fichier
  • // cherche dans le cas ou il existe
  • FILE *df;
  • // Descripteur de fichier log pour chaque thread
  • FILE *log;
  • char nom_log[MAX_BUF];
  • // longuer de la structure sockaddr client
  • int long_client;
  • // utilise pour recuperer les valeurs de retour
  • // des fonctions recvfrom et sendto
  • int envoye, recue;
  • // Tampon de lecture ecriture
  • char *buf;
  • // Pour specifie la longueur du bufer
  • int long_buf;
  • // Stocke le nom de fichier envoye par le client
  • char nom_fichier[MAX_REP_CHEMIN];
  • // Stocke le chemin d'acce au fichier
  • // retourne par la fonction recherche_fichier
  • char chemin[MAX_REP_CHEMIN];
  • // Stocke la chaine a cherche dans le fichier
  • char motif[MAX_BUF];
  • // ndice indiquant si le motif a ete trouve ou pas
  • int motif_trouve = -1;
  • // Pour le parcour du tableau de thread
  • int i;
  • // Pour compter le nombre des bloque envoye au client;
  • int num_bloc = 0;
  • // Utilise pour savoir la longueur lu par la fct read
  • int long_lu=0;
  • // Pour recevoir l'arguemt specail qui contient
  • // l'adresse du client et le descripteur de la socket
  • comp *spec = (comp *)special;
  • struct sockaddr_in *client = (struct sockaddr_in *)&spec->addr;
  • serveur = (int)spec->desc;
  • memset(nom_log,0,MAX_BUF);
  • sprintf(nom_log,"serveur-%s-%d.log",
  • inet_ntoa(client->sin_addr),pthread_self());
  • log = fopen(nom_log ,"w+");
  • if(log == NULL)
  • {
  • printf("\n Erreur d'ouverture du fichier log.\n");
  • pthread_exit(1);
  • }
  • fprintf(log," -----------------------------------------------------\n");
  • fprintf(log,"| Fichier log generer automatiquement par le serveur |");
  • fprintf(log,"\n -----------------------------------------------------\n");
  • fprintf(log, "\n Le thread %d va s'occupe de la demande du client %s\n",
  • pthread_self(),inet_ntoa(client->sin_addr));
  • // Essayer d'allouer le buffer
  • buf = (char *)malloc(MAX_BUF);
  • if (buf == NULL)
  • {
  • fprintf(log,"\n Impossible d'alloue le buffer.\n",
  • pthread_self());
  • fprintf
  • (log, "\n Arret du trait associe su client %s:%u \n",
  • inet_ntoa(client->sin_addr),
  • ntohs(client->sin_port)
  • );
  • fclose(log);
  • section_critique(log);
  • pthread_exit(1);
  • }
  • long_buf = MAX_BUF;
  • long_client = sizeof(client);
  • // Attente de messages des clients
  • // On attend un nom de fichier a cherhe
  • fprintf(log, "\n Attente du nom de fichier a cherche ... ",
  • pthread_self());
  • memset(buf,0,strlen(buf));
  • recue =
  • recv(serveur, buf, long_buf , 0);
  • if (recue < 0)
  • {
  • fprintf(log, " [FAILED]");
  • perror("Cause");
  • fclose(log);
  • close(serveur);
  • section_critique(log);
  • pthread_exit(1);
  • }
  • fprintf(log, " [OK]");
  • strcpy(nom_fichier,buf);
  • // On attend la motif a cherche dans le fichier
  • fprintf(log, "\n Attente du motif a cherche ... ",pthread_self());
  • memset(buf,0,strlen(buf));
  • recue =
  • recv(serveur, buf, long_buf , 0);
  • if (recue < 0)
  • {
  • fprintf(log," [FAILED]\n");
  • perror("Cause");
  • fclose(log);
  • close(serveur);
  • section_critique(log);
  • pthread_exit(1);
  • }
  • strcpy(motif, buf);
  • fprintf(log, " [OK]");
  • // Recherche du fichier et recuperation de sont chemin
  • // dans le cas ou il existe
  • fprintf(log, "\n Recherche du fichier %s ... ",nom_fichier);
  • memset(chemin,0,strlen(chemin));
  • strcpy(chemin,cherche_fichier(nom_fichier,log));
  • if(!strcmp(chemin,"NO_EXIST"))
  • {
  • fprintf(log, " [FAILED]\n");
  • fprintf(log, "\n Le fichier cherche n'existe pas. \n ");
  • // On envoi un message pour prevenir le client
  • // que le fichier qu'il a demande n'existe pas
  • // dans le serveur
  • fprintf(log, "\n Envoyer 'NO_EXIST' au client ... ");
  • strcpy(buf,"NO_EXIST");
  • long_buf = strlen("NO_EXIST") + 1;
  • envoye =
  • send(serveur,buf,long_buf,0);
  • if(envoye < 0)
  • {
  • fprintf(log," [FAILED]");
  • perror("Cause");
  • }
  • fprintf(log," [OK]");
  • close(serveur);
  • fclose(log);
  • section_critique(log);
  • pthread_exit(1);
  • }
  • // Si on est arrive ici, ca veut dir que le fichier existe
  • fprintf(log,"\n Le fichier existe et sont chemin est: %s\n",chemin);
  • fprintf(log, "\n Envoyer 'EXIST' au client ... ");
  • strcpy(buf,"EXIST");
  • long_buf = strlen("EXIST") + 1;
  • envoye =
  • send(serveur,buf,long_buf,0);
  • if(envoye < 0)
  • {
  • perror("Cause");
  • close(serveur);
  • fclose(log);
  • section_critique(log);
  • pthread_exit(1);
  • }
  • // On ouvre le fichier pour lecture
  • // la fonction fopen nous retourne un descripteur
  • // qui va etre utilise par la fonction fscanf;
  • df = fopen(chemin,"r+");
  • if(df != NULL)
  • {
  • // Tanque fin de fichier non atteinte on envoi un bloque de donne de taille
  • // strlen(buf) au client qui possede l'adresse client
  • while(!feof(df))
  • {
  • num_bloc ++;
  • if((long_lu = fread(buf,1,MAX_BUF,df)) < 0)
  • {
  • fprintf(log, "\n Erreur de lecture de fichier.\n");
  • perror("Cause");
  • break;
  • }
  • buf[long_lu] = '\0';
  • fprintf(log,"\n Lecture d'un bloque avec succe.");
  • // La recherche du motif dans le buffer courant
  • if(strstr(buf, motif))
  • {
  • motif_trouve = num_bloc;
  • }
  • fprintf(log,
  • "\n\t*********** Envoi du bloc N %d ************",num_bloc);
  • long_buf = strlen(buf)+1;
  • envoye =
  • send(serveur,buf, long_buf, 0);
  • if(envoye < 0)
  • {
  • fprintf(log, "\n Erreur d'envoi de donne. \n");
  • perror("Cause");
  • continue;
  • }
  • fprintf(log,"\n Les donnees on ete envoyees avec succe.");
  • } /* while(!feof(df))*/
  • } /*if(df != NULL)*/
  • else
  • {
  • fprintf(log,
  • "\n Un probleme est survennu lors de l'ouverture du fichier.");
  • perror("Cause");
  • strcpy(buf,"$ERREUR$");
  • long_buf = strlen(buf);
  • send(serveur, (char *) buf, long_buf, 0);
  • fclose(df);
  • fclose(log);
  • close(serveur);
  • section_critique(log);
  • pthread_exit(1);
  • }
  • strcpy(buf, "$FIN$");
  • long_buf = strlen(buf) + 1;
  • printf(" \n Envoye $FIN$ au client %s:%u ... ", inet_ntoa(client->sin_addr),
  • ntohs(client->sin_port));
  • fprintf(log,"\n Envoye $FIN$ au client %s:%u ... ", inet_ntoa(client->sin_addr),
  • ntohs(client->sin_port));
  • envoye =
  • send(serveur, (char *) buf, long_buf, 0);
  • if(envoye < 0)
  • {
  • printf(" [FAILED]");
  • fprintf(log, " [FAILED]");
  • perror("CAUSE");
  • }
  • else
  • {
  • fprintf(log, " [OK]");
  • printf("\n Envoi du fichier a ete termine avec succe");
  • fprintf(log, "\n ------------------------ ");
  • fprintf(log, "\n |Envoi du fichier termine| ");
  • fprintf(log, "\n ------------------------ ");
  • fprintf(log,"\n Envoyer la reponse indiquant si le motif a ete trouve ...");
  • if(motif_trouve >= 0)
  • {
  • memset(buf,0,MAX_BUF);
  • // Le serveur renvoi une reponse indiquant le numero de bloque
  • // qui contient la premiere occurence du motif cherche
  • sprintf(buf,"\n Le motif cherche existe dans le bloc %d:",motif_trouve);
  • long_buf = strlen(buf) + 1;
  • }
  • else
  • {
  • sprintf(buf,"\n Le motif cherche n'existe pas dans le fichier.");
  • long_buf = strlen(buf) + 1;
  • long_buf = strlen("\n Le motif n'existe pas dans le fichier.") + 1;
  • }
  • envoye =
  • send(serveur, buf, long_buf, 0);
  • if(envoye < 0)
  • {
  • fprintf(log, " [FAILED]");
  • }
  • else
  • {
  • fprintf(log, " [OK]");
  • printf(
  • "\n La requete du client %s:%u a ete traite avec succe.", inet_ntoa(client->sin_addr),
  • ntohs(client->sin_port));
  • fprintf(log,
  • "\n La requete du client %s:%u a ete traite avec succe.",
  • inet_ntoa(client->sin_addr),
  • ntohs(client->sin_port));
  • }
  • }
  • fclose(log);
  • fclose(df);
  • close(serveur);
  • section_critique(log);
  • return NULL;
  • }
  • ///////////////////////////////////////////////////////////////////////////
  • // Cette procedure permet de liberer un identificateur de decrementer //
  • // le nombre de clients qui se trouve dans le serveur //
  • /////////////////////////////////////////////////////////////////////////
  • void section_critique(FILE *log)
  • {
  • int i;
  • pthread_mutex_t mut;
  • // Initialisation du verrou
  • // Cette fonction retourne toujour 0
  • fprintf(log, "\n Initialisation du verrou ... ");
  • pthread_mutex_init(&mut, NULL);
  • fprintf(log, " [OK]\n");
  • // Section critique
  • fprintf(log, "\n Debut de la section critique ... ");
  • pthread_mutex_lock(&mut);
  • // Decrement le nombre de client
  • num_libre --;
  • // libere l'identificateur de thread
  • for(i = 0; i < 4; i ++)
  • if(th_occupe[i] == pthread_self())
  • th_occupe[i] = -1;
  • pthread_mutex_unlock(&mut);
  • fprintf(log, "\n Fin de la section critique ... ");
  • // Fin de la section critique
  • }
  • ///////////////////////////////////////////////////////////////////////////
  • // Cette fonction permet de cree un Socket //
  • // Ca valeur de retour est un descripteur dans la table des descripteur //
  • // du processus c'est pour cela qu'il faut un bind pour quelle soit //
  • // definie aupres du systeme //
  • /////////////////////////////////////////////////////////////////////////
  • int cree_socket(int port, FILE *hist)
  • {
  • struct sockaddr_in serveur_addr;
  • int serveur;
  • // Creation du socket
  • serveur = socket(AF_INET, SOCK_STREAM,0);
  • if(serveur < 0)
  • {
  • printf(" [FAILED]");
  • perror("Cause");
  • return -1;
  • }
  • fprintf(hist, " [OK]");
  • // La famille a laquelle appartient le socket
  • serveur_addr.sin_family = AF_INET;
  • // Adresse specifique qui permet de dir au systeme
  • // que je suis en ecoute sur tout les adresse IP entrantes
  • serveur_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  • // Le port utilise par le socket
  • serveur_addr.sin_port = htons(port);
  • fprintf(hist, "\n Attachement du socket avec une adresse ip/port ... ");
  • // Attachement du socket au systeme
  • if(bind(serveur, (struct sockaddr *) &serveur_addr, sizeof(serveur_addr)) < 0)
  • {
  • fprintf(hist, " [FAILED]");
  • perror("Cause");
  • return -1;
  • }
  • fprintf(hist, " [OK]\n");
  • return serveur;
  • }
  • ///////////////////////////////////////////////////////////////////////////
  • // Cette fonction permet de cherche un fichier //
  • // dans l'arborescence du systemes et de voir si ce fichier //
  • // contient la chaine recherche //
  • ///////////////////////////////////////////////////////////////////////////
  • char * cherche_fichier(char *nom, FILE * log)
  • {
  • static int trouve = faux;
  • // Pointeur sur descripteur de repertoire
  • DIR* rep;
  • // Pointeur sur une entree repertoire
  • struct dirent* entree;
  • // Repertoire de travail courant
  • char rtc[MAX_REP_CHEMIN + 1], sauv[MAX_REP_CHEMIN + 1];
  • //Chemin complet de notre fichier
  • static char chemin[MAX_REP_CHEMIN + 1];
  • // Utilise par stat() pour teste le type des entree
  • struct stat rep_stat;
  • char pile[MAX_REP_CHEMIN][MAX_REP_CHEMIN];
  • int som = 0;
  • strcpy(pile[som],"/");
  • som++;
  • do {
  • som --;
  • strcpy(sauv,pile[som]);
  • if (chdir(sauv) == -1)
  • {
  • fprintf(log, "\n %s",sauv);
  • fprintf(log," \n Erreur lors du changement de repertoire ...");
  • strcpy(chemin,"NO_EXIST");
  • return chemin;
  • }
  • fprintf(log, "\n Recherche dans %s: ", sauv);
  • // ouvrir le repertoir pour lecture
  • rep = opendir(".");
  • if (!rep)
  • {
  • fprintf(log, "\n Impossible de lire le repertoire %s.\n ", sauv);
  • perror("Cause");
  • strcpy(chemin,"NO_EXIST");
  • return chemin;
  • }
  • ///////////////////////////////////////////////////////////////////////
  • // Parcour du repertoire courant ainsi que tout les sous repertoire //
  • ///////////////////////////////////////////////////////////////////////
  • do
  • {
  • entree = readdir(rep);
  • if(entree == NULL)
  • {
  • fprintf(log, "\n Le parcour de %s est termine.\n",sauv);
  • break;
  • }
  • if(entree != NULL)
  • {
  • fprintf(log, "\n Entree courante est: %s", entree->d_name);
  • if ( entree->d_name && !strcmp(entree->d_name,nom))
  • {
  • if (getcwd(rtc, MAX_REP_CHEMIN) == NULL)
  • {
  • perror("Cause");
  • strcpy(chemin,"NO_EXIST");
  • return chemin;
  • }
  • if(strcmp(rtc,"/"))
  • strcat(rtc,"/");
  • strcat(rtc,entree->d_name);
  • strcpy(chemin,rtc);
  • // retourne le chemin d'acce complet du fichier
  • fprintf(log, "\n Le chemin du fichier cherche est: %s\n",
  • chemin);
  • return chemin;
  • }
  • // on evite les repertoires systemes
  • // si vous voulez effectue une recherche dans ses repertoires
  • // il faut les supprimes, mais le temps de recherche augmentera
  • // considerablement
  • if(strcmp(entree->d_name,"Recycled") == 0)
  • continue;
  • if(strcmp(entree->d_name,"dev") == 0)
  • continue;
  • if(strcmp(entree->d_name,"proc") == 0)
  • continue;
  • if(strcmp(entree->d_name,"root") == 0)
  • continue;
  • if(strcmp(entree->d_name,"mnt") == 0)
  • continue;
  • if(strcmp(entree->d_name,"lib") == 0)
  • continue;
  • if(strcmp(entree->d_name,"usr") == 0)
  • continue;
  • if(strcmp(entree->d_name,"etc") == 0)
  • continue;
  • if (strcmp(entree->d_name, ".") == 0)
  • continue;
  • if (strcmp(entree->d_name, "..") == 0)
  • continue;
  • if(entree->d_name != NULL)
  • if ( stat(entree->d_name, &rep_stat) == -1)
  • {
  • continue;
  • }
  • // On teste si l'entre courante est un repertoir
  • if (S_ISDIR(rep_stat.st_mode))
  • {
  • if(som < MAX_REP_CHEMIN )
  • {
  • if (getcwd(rtc, MAX_REP_CHEMIN) == NULL)
  • {
  • perror("Cause");
  • strcpy(chemin,"NO_EXIST");
  • return chemin;
  • }
  • if(strcmp(rtc,"/"))
  • strcat(rtc,"/");
  • strcat(rtc,entree->d_name);
  • if(strcmp(rtc, sauv) != 0) // Eviter les autoreferences
  • {
  • strcpy(pile[som],rtc);
  • som++;
  • }
  • }
  • else
  • {
  • fprintf(log, "\n Pile pleine ... arret de recherche.");
  • strcpy(chemin,"NO_EXIST");
  • return chemin;
  • }
  • } // if (S_DIR)
  • } // if(entree =! null )
  • }while(vrai);
  • closedir(rep);
  • }while(som > 0);
  • strcpy(chemin,"NO_EXIST");
  • return chemin;
  • }
  • //////////////////////////////////////////////////////////////////////////////////////////////
  • // CODE DU CLIENT //
  • //////////////////////////////////////////////////////////////////////////////////////////////
  • /* Marche sous linux/unix */
  • /* Compilation: cc ftcpc.c -o client -lpthread */
  • /* Execution: ./serveur adresse ou nom du serveur */
  • #include <arpa/inet.h>
  • #include <sys/socket.h>
  • #include <sys/types.h>
  • #include <netdb.h>
  • #include <dirent.h>
  • #include <sys/stat.h>
  • #include <string.h>
  • #include <unistd.h>
  • #include <stdio.h>
  • #include <time.h>
  • #define vrai 1
  • #define faux 0
  • // Numero du port du serveur
  • #define SERV_PORT 1200
  • // taille maximal du buffer
  • #define MAX_BUF 2048
  • // Descripteur du fichier cree pour la reception
  • FILE *fd;
  • // Le nom sous lequel le fichier transferer sera garder
  • char nom_fich_recu[MAX_BUF];
  • // Fonctions utilise par le client
  • int cree_socket();
  • ////////////////////////////////////////////////////////////////
  • // Procedure principale //
  • ///////////////////////////////////////////////////////////////
  • int main(int argc, char **argv)
  • {
  • // Buffer pour la lecture et l'ecriture dans le socket
  • char *buf;
  • int long_buf;
  • //Descripteur du client
  • int client;
  • // Utilise par send pour garder la valeur de retour
  • int envoye;
  • // Guarde la valeur de retour de la fonction recv
  • int recue;
  • // Pour la construction de l'adresse du serveur
  • struct sockaddr_in serveur;
  • int long_serveur;
  • // Pour avoir les informations concernant le serveur
  • struct hostent *h;
  • // Variable indiquant qu'on a atteint la fin de fichoer
  • int fin = faux;
  • // Pour le comptage des bloc recu
  • int num_bloc = 0;
  • printf("\n Verfication des arguments de la ligne de commande ... ");
  • if (argc != 2)
  • {
  • printf(" [FAILED]");
  • printf("\n Usage: client nom_serveur \n");
  • exit(1);
  • }
  • printf(" [OK]");
  • // creation du socket
  • printf(" \n Creation du socket ... ");
  • client = cree_socket();
  • if(client < 0)
  • {
  • perror("Cause");
  • exit(1);
  • }
  • // Allocation du buffer
  • printf(" \n Allocation du buffer ... ");
  • buf = (char *)malloc(MAX_BUF);
  • if(buf == NULL)
  • {
  • printf(" [FAILED]\n");
  • perror("Cause");
  • exit(1);
  • }
  • printf(" [OK]\n");
  • // On construit l'adresse du serveur
  • printf("\n Construction de l'adresse du serveur ... ");
  • printf(" [OK]");
  • printf("\n Resolution du nom de serveur %s ... ", argv[1]);
  • h = gethostbyname(argv[1]);
  • if (h == NULL)
  • {
  • printf(" [FAILED]\n");
  • perror("Cause");
  • exit(1);
  • }
  • printf(" [OK]\n");
  • serveur.sin_family = AF_INET;
  • serveur.sin_port = htons(SERV_PORT);
  • struct in_addr *addr_ip_serv = (struct in_addr *)h->h_addr_list[0];
  • printf("\n Adresse ip du serveur est: %s",
  • inet_ntoa(*addr_ip_serv));
  • memcpy((char*)(&serveur.sin_addr.s_addr), h->h_addr_list[0], h->h_length);
  • long_serveur = sizeof(serveur);
  • // On va envoye une demande de connexion au serveur
  • // notre protocole consiste a envoye un message contenant
  • printf("\n Demande de connexion au serveur ... ");
  • if(connect(client, (struct sockaddr *)&serveur , long_serveur) < 0)
  • {
  • printf(" [FAILED] \n");
  • perror("Cause");
  • exit(1);
  • }
  • printf(" [OK]");
  • printf("\n Attente de validation ou refus de connexion ... ");
  • memset(buf,0,strlen(buf));
  • recue =
  • recv(client, buf, long_buf, 0);
  • if (recue < 0)
  • {
  • printf(" [FAILED]");
  • perror("Cause");
  • exit(1);
  • }
  • if(strcmp(buf,"OK") != 0 && strcmp(buf,"NO") != 0)
  • {
  • printf(" [OK] \n");
  • printf("\n Attendu OK ou NO recue %s.\n", buf);
  • exit(1);
  • }
  • if(strcmp(buf,"NO") == 0)
  • {
  • printf(" [FAILED]");
  • printf("\n\t\t !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ");
  • printf("\n\t\t !!! Le serveur est charge !!! ");
  • printf("\n\t\t !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n");
  • close(client);
  • exit(1);
  • }
  • if(strcmp(buf,"OK") == 0)
  • {
  • printf(" [OK]");
  • printf("\n\t\t ***************************************");
  • printf("\n\t\t *** Le serveur a accepte la demande ***");
  • printf("\n\t\t ***************************************");
  • }
  • // On envoi le nom de fichier a cherche
  • printf("\n Entrer le nom de fichier a cherche: ");
  • scanf("%s",buf);
  • long_buf = strlen(buf) + 1;
  • printf("\n Envoi du nom de fichier ... ");
  • envoye =
  • send(client, buf, long_buf , 0);
  • if(envoye < 0)
  • {
  • printf(" [FAILED]");
  • perror("Cause");
  • close(client);
  • exit(1);
  • }
  • printf(" [OK]");
  • // On envoi la chaine a recherche dans le fichier
  • printf("\n Entrer le motif a cherche: ");
  • memset(buf,0,strlen(buf));
  • scanf("%s",buf);
  • long_buf = strlen(buf);
  • printf("\n Envoi du motif ... ");
  • envoye =
  • send(client, buf, long_buf , 0);
  • if(envoye < 0)
  • {
  • printf(" [FAILED]\n");
  • perror("Cause");
  • close(client);
  • exit(1);
  • }
  • printf(" [OK]");
  • // Reception de la reponse pour l'existence du fichier
  • printf("\n Attente de la reponse d'existance du fichier ...");
  • memset(buf,0,strlen(buf));
  • long_buf = MAX_BUF;
  • recue =
  • recv(client, buf, long_buf, 0);
  • if (recue < 0)
  • {
  • printf(" [FAILED]");
  • perror("Cause");
  • close(client);
  • exit(1);
  • }
  • printf(" [OK]");
  • if(!strcmp(buf,"EXIST"))
  • {
  • printf("\n Le serveur a trouve le fichier cherche. \n");
  • }
  • else if(!strcmp(buf,"NO_EXIST"))
  • {
  • printf("\n Le serveur n'a pas reussi a trouve le fichier.\n");
  • close(client);
  • exit(1);
  • }
  • else
  • {
  • printf(" \n Attendu 'EXIST' ou 'NO_EXIST': Recue %s \n",buf);
  • close(client);
  • exit(0);
  • }
  • sprintf(nom_fich_recu, "client%d",getpid());
  • strcat(nom_fich_recu,".log");
  • fd = fopen(nom_fich_recu,"w+");
  • printf("\n *************************************************************** ");
  • printf("\n * Reception du contenu * ");
  • printf("\n *************************************************************** \n");
  • long_buf = MAX_BUF;
  • if(fd == NULL)
  • {
  • printf("\n Impossible de cree un fichier pour la reception des donnees recu");
  • perror("Cause");
  • close(client);
  • exit(1);
  • }
  • else
  • do /* tanque non fin de fichier */
  • {
  • printf("\n Attente d'un bloque de donnee ... ");
  • // Effacer le contenu du buffer
  • long_buf = MAX_BUF;
  • memset(buf,0,MAX_BUF);
  • recue =
  • recv(client, buf, long_buf, 0);
  • if(recue < 0)
  • {
  • printf(" [FAILED]\n");
  • printf("\n Erreur lors de la reception des donnees. \n");
  • perror("Cause");
  • continue;
  • } /* if recue < 0 */
  • printf(" [OK]");
  • printf("%s",buf);
  • if(!strcmp(buf,"$FIN$") || !strcmp(buf, "$ERREUR$"))
  • {
  • fin = vrai;
  • }
  • if(fin == faux) // Car $FIN$, $ERREUR$ ne font pas partie du fichier
  • {
  • num_bloc++;
  • // Ecrire les donnees recu dans le fichier qui porte comme nom
  • // client-num_port
  • printf("\n Ecriture du bloc %d sur le fichier ... ", num_bloc);
  • if(fprintf(fd,"%s",buf) < 0)
  • {
  • printf(" [FAILED]\n");
  • perror("Cause");
  • exit(1);
  • }
  • }
  • printf(" [OK]");
  • }while(fin == faux); /* !feof(df) */
  • // On attend la reponse concernant le motif //
  • printf("\n Attente de la recpetion concernant le motif ... ");
  • long_buf = MAX_BUF;
  • memset(buf,0,MAX_BUF);
  • recue =
  • recv(client, buf, long_buf, 0);
  • if(recue < 0)
  • {
  • printf(" [FAILED]");
  • perror("Cause");
  • }
  • else
  • {
  • printf(" [OK]");
  • printf("\n %s", buf);
  • printf(" \n Le transfert est termine avec succe.");
  • printf(
  • " \n Ouvrir le fichier client%d.log pour voir le resultat de la recpetion.\n" , getpid());
  • }
  • fclose(fd);
  • close(client);
  • printf("\n");
  • return 0;
  • }
  • //////////////////////////////////////////////////////////////////
  • //Procedure aui permet la creation d'une socket //
  • //et elle nou renvoi un descripteur sur le socket ainsi cree //
  • //////////////////////////////////////////////////////////////////
  • int cree_socket()
  • {
  • int client;
  • // Creation du socket
  • client = socket(AF_INET, SOCK_STREAM, 0);
  • if(client < 0)
  • {
  • perror(" [FAILED] \n");
  • return(-1);
  • }
  • printf(" [OK]\n");
  • return client;
  • }
	//////////////////////////////////////////////////////////////////////
	//                       EL Antri Abdellah                          //
	//                    @-MAIL: El_EMIR_2002@YAHOO.FR                 //
	//              Universite DJILLALI LIABES SIDI BEL ABBES           //
	//                     Departement d'informatique                   //
	//////////////////////////////////////////////////////////////////////




/**************************************************************************/
/*				Rmarque importante					  */
/* Le serveur créé des fichiers log pour chaque client et un historique   */
/* des connexions directement dans la racine / par consequent il faut     */
/* ilo faut avoir les privileges root                                     */
/**************************************************************************/

//////////////////////////////////////////////////////////////////////////////////////////////
//							CODE DU SERVEUR                                   //
//////////////////////////////////////////////////////////////////////////////////////////////

/* Marche sous linux/unix */
/* Compilation: cc ftcps.c -o serveur -lpthreqd */
/* Execution: ./serveur 1200                    */



#include <time.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>            
#include <sys/stat.h>           
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>             
#include <unistd.h>           
#include <stdio.h>              

#define vrai 1
#define faux 0

// Cette constante permet de specifie la longueur
// maximal d'un chemin specifiant un repertoire
#define MAX_REP_CHEMIN 2048

// Cette constante desgine le nombre de thread autorise a cree
#define MAX_THREAD 4

// Ddefinie la long maximal du buffer
#define MAX_BUF 2048 

// Structure specaile pour envoyer l'adresse du client
// et le descripteur de socket
typedef struct comp{int desc; struct sockaddr_in addr;}comp;

// Declaraation des variables globales utilise
int num_libre;

// Tableau d'identificateur
pthread_t th_id[MAX_THREAD];

// Tableau pour indique les identificateur deja pris
int th_occupe [MAX_THREAD];

// Fichier contenant l'historique des connexions et des dmandes de connexion
FILE *hist;

// Declaration des fonctions et procedures 
// utiliser par notre serveur

void section_critique(FILE *);
int cree_socket(int, FILE * );
char * cherche_fichier(char *, FILE *);
void * th_trait(void  *);


// Procedure principale 
int main (int argc , char ** argv)
{
// Descripteur du serveur 
int serveur;

// Nouveau descripteur retourne par accept
int nouv_sock;

// Adresse du client
// Utilise par recvfrom pour recevoir les
// informations du client qui a envoye une 
// demande de connexion

struct sockaddr_in client;

// Longueur de la structure utilise par client
int long_client;

// Pour le parcour du tabbleau des identificateurs des thread
int i; 

// utilise pour guarder la Valeur de retour de recvfrom
int recue;

// Utiliser pour guarder la valeur de retour de sendto
int envoye;

// Utilise pour la lecture de la demande de connexion
char *buf;
int long_buf;

// Pour lire la date
time_t temp;

comp special;


system("clear");
printf("\n Arguments de la ligne de commande ... ");

if (argc != 2)
   {
   printf(" [FAILED]");
   printf("\n Usage: serveur num_proto\n");
   exit(1);
   }
printf(" [OK]");

// Creation du fichier historique
printf("\n Creation du fichier historique ... ");
hist = fopen("historique","w+");
if(hist == NULL)
  {
  printf(" [FAILED]");	  
  perror("Cause");
  exit(1);
  }	  
printf(" [OK]");	  

time(&temp);
fprintf(hist," -------------------------------------------------\n");
fprintf(hist,"| Ce fichier contient l'historique des connexions |\n");
fprintf(hist," -------------------------------------------------\n");

fprintf(hist," Date de creation: %s \n ", ctime(&temp) );
// Initialisation du buffer
// On va essayer d'alloue MAX_BUF octet

printf("\n Allocation du buffer ... ");
fprintf(hist, "\n Allocation du buffer ... ");
buf = (char *)malloc(MAX_BUF);
if(buf == NULL)
  {
  printf("\n Impossible d'alloue de l'espace pour le buffer");
  // Sans le buffer on ne peut rien faire
  exit(1);
  }
printf(" [OK]");
fprintf(hist, " [OK]");
       
// Initialisation du tableau des threads
printf("\n Initialisation du tableau d'id de thread ... ");
fprintf(hist, "\n Initialisation du tableau d'id de thread ... ");
for (i = 0; i < 4; i++)
   {
   th_occupe[i] = -1;
   }
printf(" [OK]");
fprintf(hist, " [OK]");

// Initialisation num_libre a 0
num_libre = 0;

// creation du socket
fprintf(hist, "\n Creation de socket sur le port %d... ",atoi(argv[1]));
printf("\n Creation de socket sur le port %d... ",atoi(argv[1]));
serveur = cree_socket(atoi(argv[1]),hist);
if(serveur == -1)
  {
  printf(" [FAILED]\n");	  
  exit(1);
  }

printf(" [OK]\n");	  

fprintf(hist, " Fixer la file d'attente par 5 ... ");
printf(" Fixer la file d'attente par 5 ... ");
if(listen(serveur, 5) == -1)
  {
  printf(" [FAILED]\n");
  fprintf(hist, " [FAILED]\n");
  perror("Cause");
  exit(1);
  }
printf(" [OK]\n");
fprintf(hist, " [OK]\n");
printf("\n \t  Le serveur va entre dans une boucle infini  \n");
printf("   \t  =========================================   ");
freopen("/historique","a+",hist);	

      ////////////////////////////////////////////////////////////
      //         Boucle de gestion des connexions               //
      ///////////////////////////////////////////////////////////

while(vrai)
{
fflush(stdout);//vidage de la sortie standard

printf("\n \t        Attente des demandes de connexion      ");
printf("\n");

// Le serveur attend une demande de connexion 
fprintf(hist, "\n Attente de demande de connexion ... ");
long_client = sizeof(client);
nouv_sock = accept(serveur,(struct sockaddr *) &client,&long_client);
if(nouv_sock < 0)
  {
  fprintf(hist, " [FAILED]\n");	  
  perror("Cause");
  continue ; // On neglige la requete
  }	  
fprintf(hist, " [OK]");   

// On doit recupere les informations du client
// qui a demande une connexion
printf("\n %s:%u demande la connexion au serveur ...", 
	inet_ntoa(client.sin_addr),ntohs(client.sin_port));
fprintf(hist, "\n  Une demande de connexion est recue:\n");
fprintf(hist, "  _==================================_\n");
fprintf(hist, "\t * Famille du Socket client: %x\n", ntohs(client.sin_family));
fprintf(hist, "\t * Port client: %u\n", ntohs(client.sin_port));
fprintf(hist, "\t * IP client:  %s\n", inet_ntoa(client.sin_addr));



if(num_libre > 3)
   {
   strcpy(buf,"NO");
   long_buf = strlen("NO") + 1;
   fprintf(hist, "\n Le serveur va envoye un refus de connexion ...");
   envoye =
            send(nouv_sock , buf , long_buf , 0);
   if(envoye < 0)
     {
      fprintf(hist, " [FAILED]\n");
      perror("Cause");
      continue ;
      }
   printf(" [OK]\n");
   printf("\n Connexion du %s:%u refuse: depacement de capacite \n",
                 inet_ntoa(client.sin_addr),ntohs(client.sin_port));
   fprintf(hist, " [OK]\n");
   fprintf(hist,"\n|**************************************************|");
   fprintf(hist,"\n|        DEPACEMENT DE  CAPACITE  DU SERVEUR       |"); 
   fprintf(hist, "\n|     Connexion du client %s refuse       |", 
          inet_ntoa(client.sin_addr));
   fprintf(hist,"\n|**************************************************|");
   } 
    else
        {
        strcpy(buf,"OK");
        long_buf = strlen("OK") + 1;
	fprintf(hist, " Le serveur envoi une acceptation de connexion ... ");
        envoye =
                 send(nouv_sock,buf,long_buf,0);
        if(envoye < 0)
          {
           fprintf(hist," [FAILED]\n");
           perror("Cause");
           continue;
          }
        fprintf(hist, " [OK]\n");
        num_libre ++;

	// On cherche un identificateur libre
        for(i = 0; i < 4; i++)
	    if(th_occupe[i]  == -1)
	       {
	        // La structure special contient le nom de fichier
		// la chaine a recherche
		// et l'adresse du client
		// creation du thread associe au client
		fprintf(hist, "\n Creation de thread ... ");
		special.addr = client;
		special.desc = nouv_sock;
                if(
		   pthread_create(&th_id[i], 
                		    NULL,(void *) th_trait, 
	                 	     (void *)&special)  != 0
		   )
		   {
		   fprintf(hist, " [FAILED]\n");
		   exit(1);
		   }
	       th_occupe[i] = th_id[i];   
               break;
               }
        } 
 freopen("/historique","a+",hist);	
 }// while(true)

}

// Thread  dedie  pour la recherche de fichier
// Et la recherche des motifs dans un fichier

void * th_trait(void *special)
{

// Descipteur de la socket bidirectionnelle
// retourne par accept
int serveur;

// Descripteur de fichier 
// utilise par fopen pour la lecture de fichier
// cherche dans le cas ou il existe

FILE *df;

// Descripteur de fichier log pour chaque thread
FILE *log;
char nom_log[MAX_BUF];


// longuer de la structure sockaddr client
int long_client;

// utilise pour recuperer les valeurs de retour
// des fonctions recvfrom et sendto
int envoye, recue;

// Tampon de lecture ecriture
char *buf;

// Pour specifie la longueur du bufer
int long_buf;

// Stocke le nom de fichier envoye par le client
char nom_fichier[MAX_REP_CHEMIN];

// Stocke le chemin d'acce au fichier
// retourne par la fonction recherche_fichier
char chemin[MAX_REP_CHEMIN];

// Stocke la chaine a cherche dans le fichier
char motif[MAX_BUF];
// ndice indiquant si le motif a ete trouve ou pas
int motif_trouve = -1;

// Pour le parcour du tableau de thread
int i;

// Pour compter le nombre des bloque envoye au client;
int num_bloc = 0;

// Utilise pour savoir la longueur lu par la fct read
int long_lu=0;
 
// Pour recevoir l'arguemt specail qui contient
// l'adresse du client et le descripteur de la socket
comp *spec = (comp *)special;

struct sockaddr_in *client = (struct sockaddr_in *)&spec->addr; 

serveur = (int)spec->desc;


memset(nom_log,0,MAX_BUF);
sprintf(nom_log,"serveur-%s-%d.log", 
       inet_ntoa(client->sin_addr),pthread_self());
log = fopen(nom_log ,"w+");
if(log == NULL)
   {
   printf("\n Erreur d'ouverture du fichier log.\n");
   pthread_exit(1);
   }

fprintf(log," -----------------------------------------------------\n");
fprintf(log,"| Fichier log generer automatiquement par le serveur |");
fprintf(log,"\n -----------------------------------------------------\n");

fprintf(log, "\n Le thread %d va s'occupe de la demande du client  %s\n",
       pthread_self(),inet_ntoa(client->sin_addr));

// Essayer d'allouer le buffer
buf = (char *)malloc(MAX_BUF); 
if (buf == NULL)
    {
    fprintf(log,"\n Impossible d'alloue le buffer.\n", 
           pthread_self());
    fprintf
	  (log, "\n Arret du trait associe su client %s:%u \n",
          inet_ntoa(client->sin_addr),
	  ntohs(client->sin_port)
	  );
    fclose(log);
    section_critique(log);
    pthread_exit(1);
    }
 
long_buf = MAX_BUF; 
long_client = sizeof(client);


// Attente de messages des clients
// On attend un nom de fichier a cherhe 
fprintf(log, "\n Attente du nom de fichier a cherche ... ",
        pthread_self()); 
memset(buf,0,strlen(buf));
recue = 
        recv(serveur, buf, long_buf , 0);
if (recue < 0)
    {
      fprintf(log, " [FAILED]");
      perror("Cause");
      fclose(log);
      close(serveur);
      section_critique(log);
      pthread_exit(1);
    }
  
fprintf(log, " [OK]");
strcpy(nom_fichier,buf);

// On attend la motif a cherche dans le fichier

 fprintf(log, "\n Attente du motif a cherche ... ",pthread_self());
 memset(buf,0,strlen(buf));
 recue = 
	 recv(serveur, buf, long_buf , 0);
 if (recue < 0)
    {
      fprintf(log," [FAILED]\n");
      perror("Cause");
      fclose(log);
      close(serveur);
      section_critique(log);
      pthread_exit(1);
    }
 strcpy(motif, buf);
 fprintf(log, " [OK]"); 

// Recherche du fichier et recuperation de sont chemin
// dans le cas ou il existe
 fprintf(log, "\n Recherche du fichier %s ... ",nom_fichier);
 memset(chemin,0,strlen(chemin));

 strcpy(chemin,cherche_fichier(nom_fichier,log));
 if(!strcmp(chemin,"NO_EXIST"))
   {
   fprintf(log, " [FAILED]\n");
   fprintf(log, "\n Le fichier cherche n'existe pas. \n ");
   // On envoi un message pour prevenir le client
   // que le fichier qu'il a demande n'existe pas
   // dans le serveur
   fprintf(log, "\n Envoyer  'NO_EXIST' au client ... ");
   strcpy(buf,"NO_EXIST");
   long_buf = strlen("NO_EXIST") + 1;
   envoye =
           send(serveur,buf,long_buf,0);
    if(envoye < 0)
       {
       fprintf(log," [FAILED]");
       perror("Cause");
       }
  fprintf(log," [OK]");
  close(serveur);
  fclose(log);
  section_critique(log);
  pthread_exit(1);
  }	


// Si on est arrive ici, ca veut dir que le fichier existe
fprintf(log,"\n Le fichier existe et sont chemin est: %s\n",chemin);


fprintf(log, "\n Envoyer 'EXIST' au client ... ");
strcpy(buf,"EXIST");
long_buf = strlen("EXIST") + 1;

envoye =
         send(serveur,buf,long_buf,0);
if(envoye < 0)
  {
  perror("Cause");
  close(serveur);
  fclose(log);
  section_critique(log);
  pthread_exit(1);
  }

// On ouvre le fichier pour lecture 
// la fonction fopen nous retourne un descripteur 
// qui va etre utilise par la fonction fscanf;

df = fopen(chemin,"r+");

if(df != NULL)
  {

   // Tanque fin de fichier non atteinte on envoi un bloque de donne de taille
   // strlen(buf) au client qui possede l'adresse client
   while(!feof(df))
      {
      num_bloc ++; 
      if((long_lu = fread(buf,1,MAX_BUF,df)) < 0)
         {
         fprintf(log, "\n Erreur de lecture de fichier.\n");
         perror("Cause");
         break;         
         }
      buf[long_lu] = '\0';
      fprintf(log,"\n Lecture d'un bloque avec succe.");
      // La recherche du motif dans le buffer courant
      if(strstr(buf, motif))
	 {
	 motif_trouve = num_bloc;	 
	 }
       
        fprintf(log,
              "\n\t*********** Envoi du bloc N %d ************",num_bloc);
	long_buf = strlen(buf)+1;
        envoye = 
 	         send(serveur,buf, long_buf, 0);
        if(envoye < 0)
           {
           fprintf(log, "\n Erreur d'envoi de donne. \n");
           perror("Cause");
           continue;
           }
        fprintf(log,"\n Les donnees on ete envoyees avec succe.");
        

     }                 /* while(!feof(df))*/  

  }                    /*if(df != NULL)*/

   else 
        {
        fprintf(log, 
              "\n Un probleme est survennu lors de l'ouverture du fichier.");
        perror("Cause");
        strcpy(buf,"$ERREUR$");
        long_buf = strlen(buf);
        send(serveur, (char *) buf, long_buf, 0);
        fclose(df);
        fclose(log);
        close(serveur);
        section_critique(log);
        pthread_exit(1);
        }

strcpy(buf, "$FIN$");
long_buf = strlen(buf) + 1;
printf(" \n Envoye $FIN$ au client %s:%u ... ", inet_ntoa(client->sin_addr), 
		ntohs(client->sin_port));
fprintf(log,"\n Envoye $FIN$ au client %s:%u ... ", inet_ntoa(client->sin_addr),
		ntohs(client->sin_port));
envoye =
          send(serveur, (char *) buf, long_buf, 0);       

if(envoye < 0)
  {
  printf(" [FAILED]");
  fprintf(log, " [FAILED]");
  perror("CAUSE");
  }
  else 
    {
    fprintf(log, " [OK]");
    printf("\n Envoi du fichier a ete termine avec succe");
    fprintf(log, "\n  ------------------------  ");
    fprintf(log, "\n |Envoi du fichier termine| ");
    fprintf(log, "\n  ------------------------  ");

    fprintf(log,"\n Envoyer la reponse indiquant si le motif a ete trouve ...");
    if(motif_trouve >= 0)
     {
     memset(buf,0,MAX_BUF);
     // Le serveur renvoi une reponse indiquant le numero de bloque
     // qui contient la premiere occurence du motif cherche
     sprintf(buf,"\n Le motif cherche existe dans le bloc %d:",motif_trouve);
     long_buf = strlen(buf) + 1;
     }
      else 
          {
          sprintf(buf,"\n Le motif cherche n'existe pas dans le fichier.");
          long_buf = strlen(buf) + 1;
          long_buf = strlen("\n Le motif n'existe pas dans le fichier.") + 1;
          }
     envoye =
	      send(serveur, buf, long_buf, 0);
     if(envoye < 0)
	{
	fprintf(log, " [FAILED]");
	}
        else
	     {	
              fprintf(log, " [OK]");	      
	      printf(
		      "\n La requete du client %s:%u a ete traite avec succe.", inet_ntoa(client->sin_addr),
			    ntohs(client->sin_port));
              fprintf(log,
   		    "\n La requete du client %s:%u a ete traite avec succe.", 
                              inet_ntoa(client->sin_addr),
			      ntohs(client->sin_port));
             }
     }
fclose(log);
fclose(df);
close(serveur);
section_critique(log);

return NULL;
}


///////////////////////////////////////////////////////////////////////////
// Cette procedure permet de liberer un identificateur de decrementer   //
// le nombre de clients qui se trouve dans le serveur                   //
/////////////////////////////////////////////////////////////////////////

void section_critique(FILE *log)               
{
int i;
pthread_mutex_t mut;

// Initialisation du verrou
// Cette fonction retourne toujour 0
fprintf(log, "\n Initialisation du verrou ... ");  
pthread_mutex_init(&mut, NULL);
fprintf(log, " [OK]\n");


// Section critique
fprintf(log, "\n Debut de la section critique ... ");  
pthread_mutex_lock(&mut);
// Decrement le nombre de client
num_libre --;
// libere l'identificateur de thread
for(i = 0; i < 4; i ++)
   if(th_occupe[i] == pthread_self())
     th_occupe[i] = -1;
pthread_mutex_unlock(&mut);       
fprintf(log, "\n Fin de la section critique ... ");  
// Fin de la section critique
}

///////////////////////////////////////////////////////////////////////////
// Cette fonction permet de cree un Socket                               //
// Ca valeur de retour est un descripteur dans la table des descripteur  //
// du processus c'est pour cela qu'il faut un bind pour quelle soit     //
// definie aupres du systeme                                            // 
/////////////////////////////////////////////////////////////////////////


int cree_socket(int port, FILE *hist)
{

  struct sockaddr_in serveur_addr;
  int serveur;
  
  // Creation du socket
  serveur = socket(AF_INET, SOCK_STREAM,0);
  if(serveur < 0)
    {
      printf(" [FAILED]");
      perror("Cause");
      return -1;
    }
  fprintf(hist, " [OK]");
  // La famille a laquelle appartient le socket
  serveur_addr.sin_family = AF_INET;
  
  // Adresse specifique qui permet de dir au systeme
  // que je suis en ecoute sur tout les adresse IP entrantes
  serveur_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  
  // Le port utilise par le socket
  serveur_addr.sin_port = htons(port);
 
 fprintf(hist, "\n Attachement du socket avec une adresse ip/port ... ");
 // Attachement du socket au systeme
  if(bind(serveur, (struct sockaddr *) &serveur_addr, sizeof(serveur_addr)) < 0)
    {
      fprintf(hist, " [FAILED]");
      perror("Cause");
      return -1;
    }
  fprintf(hist, " [OK]\n"); 
  return serveur;
}


///////////////////////////////////////////////////////////////////////////
// Cette fonction permet de cherche un fichier                           //
// dans l'arborescence du systemes et de voir si ce fichier              //
// contient la chaine recherche                                          //
///////////////////////////////////////////////////////////////////////////

char * cherche_fichier(char *nom, FILE * log)
{

    static int trouve = faux;

    // Pointeur sur descripteur de repertoire          
    DIR* rep;                            

    // Pointeur sur une entree repertoire              
    struct dirent* entree; 

    // Repertoire de travail courant                  
    char rtc[MAX_REP_CHEMIN + 1], sauv[MAX_REP_CHEMIN + 1];
    //Chemin complet de notre fichier
    static char chemin[MAX_REP_