From b00f35cca5bfdb24e46aa76f2edb459969c58a43 Mon Sep 17 00:00:00 2001 From: hoverwars Date: Sat, 11 Oct 2025 11:11:31 +0200 Subject: [PATCH 1/4] [FEAT] split some code from server.c --- server/defi.c | 77 ++++++++++++++ server/event_interceptor.c | 6 ++ server/event_interceptor.h | 7 ++ server/events.h | 15 +++ server/game.c | 31 ++++++ server/models.h | 31 ++++++ server/server.c | 199 ++++++------------------------------- shared/event_handler.c | 2 +- shared/socket.c | 13 +++ shared/socket.h | 6 ++ 10 files changed, 215 insertions(+), 172 deletions(-) create mode 100644 server/defi.c create mode 100644 server/event_interceptor.c create mode 100644 server/event_interceptor.h create mode 100644 server/events.h create mode 100644 server/game.c create mode 100644 server/models.h create mode 100644 shared/socket.c create mode 100644 shared/socket.h diff --git a/server/defi.c b/server/defi.c new file mode 100644 index 0000000..aec8302 --- /dev/null +++ b/server/defi.c @@ -0,0 +1,77 @@ +#include "events.h" + +void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p) { + // argv[0] = "DEFI", argv[1] = pseudo_local, argv[2] = adversaire + + if (argc < 3) { + envoyer_message(sock, "ERREUR_PROTOCOLE Commande DEFI incomplete. Usage: DEFI "); + return; + } + + const char *pseudo_local = argv[1]; + const char *adversaire = argv[2]; + + if (strcmp(pseudo_local, adversaire) == 0) { + envoyer_message(sock, "ERREUR_DEFI Vous ne pouvez pas vous defier vous-meme."); + return; + } + + // ENVOI AU PÈRE VIA IPC : DEFI + char ipc_msg[MAX_BUFFER]; + snprintf(ipc_msg, MAX_BUFFER, "DEFI %s %s", pseudo_local, adversaire); + + envoyer_ipc(pipe_write_to_p, ipc_msg); + + printf("FIL (%s): Defi envoye au PERE pour repartition vers %s.\n", pseudo_local, adversaire); + envoyer_message(sock, "DEFI_ENVOYE En attente de la reponse de l'adversaire..."); +} + +void handle_refuse(int sock, int argc, char** argv, int pipe_write_to_p) { + // argv[0] = "REFUSE", argv[1] = pseudo_local, argv[2] = defiante + + if (argc < 3) { + envoyer_message(sock, "ERREUR_PROTOCOLE Commande REFUSE incomplete. Usage: REFUSE "); + return; + } + + const char *pseudo_local = argv[1]; + const char *defiante = argv[2]; + + if (strcmp(pseudo_local, defiante) == 0) { + envoyer_message(sock, "ERREUR_REFUSE Vous ne pouvez pas vous refuser vous-meme."); + return; + } + + // ENVOI AU PÈRE VIA IPC : REFUSE + char ipc_msg[MAX_BUFFER]; + snprintf(ipc_msg, MAX_BUFFER, "REFUSE %s %s", pseudo_local, defiante); + + envoyer_ipc(pipe_write_to_p, ipc_msg); + + printf("FIL (%s): Refus de defi envoye au PERE pour notification vers %s.\n", pseudo_local, defiante); + envoyer_message(sock, "DEFI_REFUSE_ENVOYE Refus du defi envoye."); +} + +void handle_accept(int sock, int argc, char** argv, int pipe_write_to_p) { + // argv[0] = "ACCEPT", argv[1] = pseudo_local (défié), argv[2] = defiante (défiant) + if (argc < 3) { + envoyer_message(sock, "ERREUR_PROTOCOLE Commande ACCEPT incomplete. Usage: ACCEPT "); + return; + } + + const char *pseudo_local = argv[1]; + const char *defiante = argv[2]; + + if (strcmp(pseudo_local, defiante) == 0) { + envoyer_message(sock, "ERREUR_ACCEPT Vous ne pouvez pas accepter votre propre defi."); + return; + } + + // ENVOI AU PÈRE VIA IPC : ACCEPT + char ipc_msg[MAX_BUFFER]; + snprintf(ipc_msg, MAX_BUFFER, "ACCEPT %s %s", pseudo_local, defiante); + envoyer_ipc(pipe_write_to_p, ipc_msg); + + // Accusé de réception côté client (le père enverra ensuite les notifications aux 2 joueurs) + envoyer_message(sock, "DEFI_ACCEPT_ENVOYE Acceptation envoyee. En attente de synchronisation..."); +} \ No newline at end of file diff --git a/server/event_interceptor.c b/server/event_interceptor.c new file mode 100644 index 0000000..01b9ef7 --- /dev/null +++ b/server/event_interceptor.c @@ -0,0 +1,6 @@ +#include "event_interceptor.h" + +void intercep_event(int sock, int pipe) +{ + +} \ No newline at end of file diff --git a/server/event_interceptor.h b/server/event_interceptor.h new file mode 100644 index 0000000..b582c70 --- /dev/null +++ b/server/event_interceptor.h @@ -0,0 +1,7 @@ +#include "../shared/socket.h" + +/** + * Intercept an event received by one of the child processes. + * The goal of this method is to transmit it to the main process that will deal with received data. + */ +void intercept_event(int sock, int pipe); \ No newline at end of file diff --git a/server/events.h b/server/events.h new file mode 100644 index 0000000..b2331aa --- /dev/null +++ b/server/events.h @@ -0,0 +1,15 @@ +#include +#include +#include +#include "models.h" +#include "../shared/socket.h" + +// Events related to challenges +void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p); +void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p); +void handle_accept(int sock, int argc, char** argv, int pipe_write_to_p); + +// Events related to game itself + +void handle_move(int sock, int argc, char** argv, int pipe_write_to_p); +void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p); \ No newline at end of file diff --git a/server/game.c b/server/game.c new file mode 100644 index 0000000..d8025e8 --- /dev/null +++ b/server/game.c @@ -0,0 +1,31 @@ +#include "events.h" + +void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p) { + // Le fils doit informer le père de la déconnexion + envoyer_ipc(pipe_write_to_p, "QUIT"); +} + +void handle_move(int sock, int argc, char** argv, int pipe_write_to_p) { + // argv[0] = "MOVE", argv[1] = pseudo_local, argv[2] = trou_idx + if (argc < 3) { + envoyer_message(sock, "ERREUR_PROTOCOLE Commande MOVE incomplete. Usage: MOVE "); + return; + } + + const char *pseudo_local = argv[1]; + const char *trou_str = argv[2]; + + // Validation simple locale (format) + int trou_idx = atoi(trou_str); + if (trou_idx < 0 || trou_idx >= NB_TROUS_CAMP) { + envoyer_message(sock, "ERREUR_COUP Trou invalide (0..5)."); + return; + } + + // ENVOI AU PÈRE VIA IPC : MOVE + char ipc_msg[MAX_BUFFER]; + snprintf(ipc_msg, MAX_BUFFER, "MOVE %s %d", pseudo_local, trou_idx); + envoyer_ipc(pipe_write_to_p, ipc_msg); + + // L'ACK et la synchronisation seront gérées par le PÈRE +} \ No newline at end of file diff --git a/server/models.h b/server/models.h new file mode 100644 index 0000000..14f4d4b --- /dev/null +++ b/server/models.h @@ -0,0 +1,31 @@ +#ifndef MODEL_H +#define MODEL_H + +#include +#include "../shared/awale.h" + +// Constants +#define MAX_PSEUDO_LEN 32 +#define MAX_BUFFER 256 + +// Structure pour stocker les informations des joueurs actifs, qui sont connectés au serveur. +typedef struct { + char pseudo[MAX_PSEUDO_LEN]; + pid_t pid; + int pipe_p_to_f; // Descripteur d'écriture du PÈRE (pour envoyer au FILS) + int pipe_f_to_p; // Descripteur de lecture du PÈRE (pour recevoir du FILS) + int en_partie; // 1 si le joueur est en partie, 0 sinon + int match_id; // Identifiant du match en cours, -1 sinon + char adversaire[MAX_PSEUDO_LEN]; // Pseudo de l'adversaire si en partie + int victoires; // Compteur de victoires (runtime) +} JoueurActif; + + +typedef struct { + char sud[MAX_PSEUDO_LEN]; + char nord[MAX_PSEUDO_LEN]; + AwalePartie partie; // Partie locale au serveur + int actif; // 1 si match actif +} Match; + +#endif \ No newline at end of file diff --git a/server/server.c b/server/server.c index e53db30..afb27f1 100644 --- a/server/server.c +++ b/server/server.c @@ -3,10 +3,8 @@ */ #include -#include "../shared/event_handler.h" #include #include -#include #include #include #include @@ -16,42 +14,45 @@ #include #include #include // Pour fcntl et O_NONBLOCK -#include "awale.h" +#include "events.h" +#include "models.h" +#include "../shared/event_handler.h" +#include "../shared/socket.h" // --- Constantes et structures --- #define MAX_JOUEURS 100 -#define MAX_PSEUDO_LEN 32 -#define MAX_BUFFER 256 #define MAX_TOKENS 12 +#define MAX_MATCHES 100 -// Structure pour stocker les informations des joueurs actifs (géré par le père) -typedef struct { - char pseudo[MAX_PSEUDO_LEN]; - pid_t pid; - int pipe_p_to_f; // Descripteur d'écriture du PÈRE (pour envoyer au FILS) - int pipe_f_to_p; // Descripteur de lecture du PÈRE (pour recevoir du FILS) - int en_partie; // 1 si le joueur est en partie, 0 sinon - int match_id; // Identifiant du match en cours, -1 sinon - char adversaire[MAX_PSEUDO_LEN]; // Pseudo de l'adversaire si en partie - int victoires; // Compteur de victoires (runtime) -} JoueurActif; +void handle_refuse(int sock, int argc, char** argv, int pipe_write_to_p); +void handle_msg(int sock, int argc, char** argv, int pipe_write_to_p); +void handle_brc(int sock, int argc, char** argv, int pipe_write_to_p); +void handle_surr(int sock, int argc, char** argv, int pipe_write_to_p); +// Store active players JoueurActif joueurs_actifs[MAX_JOUEURS]; int nb_joueurs_actifs = 0; -// ================== Gestion des Parties côté Serveur (PÈRE) ================== +// Store active matchs +Match matches[MAX_MATCHES]; +int nb_matches = 0; -#define MAX_MATCHES 100 +// Information related to event handling. The client send events to the server that handle them by matching one event label with a reaction function. +char* tableau_evenements[] = {"DEFI", "QUIT", "ACCEPT", "REFUSE", "MOVE", "MSG", "BRC", "SURR", NULL}; -typedef struct { - char sud[MAX_PSEUDO_LEN]; - char nord[MAX_PSEUDO_LEN]; - AwalePartie partie; // Partie locale au serveur - int actif; // 1 si match actif -} Match; +cmd_handler_func tableau_fonctions[] = { + handle_defi, + handle_quit, + handle_accept, + handle_refuse, + handle_move, + handle_msg, + handle_brc, + handle_surr, + NULL +}; -Match matches[MAX_MATCHES]; -int nb_matches = 0; +// ================== Gestion des Parties côté Serveur (PÈRE) ================== int trouver_match_index(const char* sud, const char* nord) { for (int i = 0; i < nb_matches; i++) { @@ -104,22 +105,13 @@ int creer_match(const char* sud, const char* nord) { int ajouter_pseudo(const char *pseudo, pid_t fils_pid, int p_to_f_fd, int f_to_p_fd); void retirer_pseudo(const char *pseudo); void envoyer_message(int sock, const char *msg); -void envoyer_ipc(int pipe_fd, const char *msg); + int trouver_index_joueur(const char *pseudo); void handle_inscription_and_fork(int sockfd_ecoute, int newsockfd, const struct sockaddr_in *cli_addr); // Ajout des descripteurs de pipe pour handle_client void handle_client(int newsockfd, const char *pseudo, const char *ip_client, int pipe_read_from_p, int pipe_write_to_p); -void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_accept(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_move(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_refuse(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_msg(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_brc(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_surr(int sock, int argc, char** argv, int pipe_write_to_p); - // Gestionnaire de signal pour nettoyer les processus fils terminés (zombies) void sigchld_handler(int s) @@ -208,126 +200,6 @@ void retirer_pseudo(const char *pseudo) { // COMMUNICATION (IPC & SOCKETS) // ========================================================================= -void envoyer_message(int sock, const char *msg) { - write(sock, msg, strlen(msg)); - write(sock, "\n", 1); -} - -void envoyer_ipc(int pipe_fd, const char *msg) { - if (write(pipe_fd, msg, strlen(msg)) < 0) { - perror("Erreur ecriture IPC"); - } - write(pipe_fd, "\n", 1); // Délimiteur -} - - -// --- Fonctions de gestion des commandes (FILS) --- - -void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p) { - // Le fils doit informer le père de la déconnexion - envoyer_ipc(pipe_write_to_p, "QUIT"); -} - -void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p) { - // argv[0] = "DEFI", argv[1] = pseudo_local, argv[2] = adversaire - - if (argc < 3) { - envoyer_message(sock, "ERREUR_PROTOCOLE Commande DEFI incomplete. Usage: DEFI "); - return; - } - - const char *pseudo_local = argv[1]; - const char *adversaire = argv[2]; - - if (strcmp(pseudo_local, adversaire) == 0) { - envoyer_message(sock, "ERREUR_DEFI Vous ne pouvez pas vous defier vous-meme."); - return; - } - - // ENVOI AU PÈRE VIA IPC : DEFI - char ipc_msg[MAX_BUFFER]; - snprintf(ipc_msg, MAX_BUFFER, "DEFI %s %s", pseudo_local, adversaire); - - envoyer_ipc(pipe_write_to_p, ipc_msg); - - printf("FIL (%s): Defi envoye au PERE pour repartition vers %s.\n", pseudo_local, adversaire); - envoyer_message(sock, "DEFI_ENVOYE En attente de la reponse de l'adversaire..."); -} - -void handle_refuse(int sock, int argc, char** argv, int pipe_write_to_p) { - // argv[0] = "REFUSE", argv[1] = pseudo_local, argv[2] = defiante - - if (argc < 3) { - envoyer_message(sock, "ERREUR_PROTOCOLE Commande REFUSE incomplete. Usage: REFUSE "); - return; - } - - const char *pseudo_local = argv[1]; - const char *defiante = argv[2]; - - if (strcmp(pseudo_local, defiante) == 0) { - envoyer_message(sock, "ERREUR_REFUSE Vous ne pouvez pas vous refuser vous-meme."); - return; - } - - // ENVOI AU PÈRE VIA IPC : REFUSE - char ipc_msg[MAX_BUFFER]; - snprintf(ipc_msg, MAX_BUFFER, "REFUSE %s %s", pseudo_local, defiante); - - envoyer_ipc(pipe_write_to_p, ipc_msg); - - printf("FIL (%s): Refus de defi envoye au PERE pour notification vers %s.\n", pseudo_local, defiante); - envoyer_message(sock, "DEFI_REFUSE_ENVOYE Refus du defi envoye."); -} - -void handle_accept(int sock, int argc, char** argv, int pipe_write_to_p) { - // argv[0] = "ACCEPT", argv[1] = pseudo_local (défié), argv[2] = defiante (défiant) - if (argc < 3) { - envoyer_message(sock, "ERREUR_PROTOCOLE Commande ACCEPT incomplete. Usage: ACCEPT "); - return; - } - - const char *pseudo_local = argv[1]; - const char *defiante = argv[2]; - - if (strcmp(pseudo_local, defiante) == 0) { - envoyer_message(sock, "ERREUR_ACCEPT Vous ne pouvez pas accepter votre propre defi."); - return; - } - - // ENVOI AU PÈRE VIA IPC : ACCEPT - char ipc_msg[MAX_BUFFER]; - snprintf(ipc_msg, MAX_BUFFER, "ACCEPT %s %s", pseudo_local, defiante); - envoyer_ipc(pipe_write_to_p, ipc_msg); - - // Accusé de réception côté client (le père enverra ensuite les notifications aux 2 joueurs) - envoyer_message(sock, "DEFI_ACCEPT_ENVOYE Acceptation envoyee. En attente de synchronisation..."); -} - -void handle_move(int sock, int argc, char** argv, int pipe_write_to_p) { - // argv[0] = "MOVE", argv[1] = pseudo_local, argv[2] = trou_idx - if (argc < 3) { - envoyer_message(sock, "ERREUR_PROTOCOLE Commande MOVE incomplete. Usage: MOVE "); - return; - } - - const char *pseudo_local = argv[1]; - const char *trou_str = argv[2]; - - // Validation simple locale (format) - int trou_idx = atoi(trou_str); - if (trou_idx < 0 || trou_idx >= NB_TROUS_CAMP) { - envoyer_message(sock, "ERREUR_COUP Trou invalide (0..5)."); - return; - } - - // ENVOI AU PÈRE VIA IPC : MOVE - char ipc_msg[MAX_BUFFER]; - snprintf(ipc_msg, MAX_BUFFER, "MOVE %s %d", pseudo_local, trou_idx); - envoyer_ipc(pipe_write_to_p, ipc_msg); - - // L'ACK et la synchronisation seront gérées par le PÈRE -} // --- Table de Dispatch --- @@ -386,21 +258,6 @@ void handle_surr(int sock, int argc, char** argv, int pipe_write_to_p) { envoyer_ipc(pipe_write_to_p, ipc_msg); } -char* tableau_evenements[] = {"DEFI", "QUIT", "ACCEPT", "REFUSE", "MOVE", "MSG", "BRC", "SURR", NULL}; - -cmd_handler_func tableau_fonctions[] = { - handle_defi, - handle_quit, - handle_accept, - handle_refuse, - handle_move, - handle_msg, - handle_brc, - handle_surr, - NULL -}; - - // ========================================================================= // GESTION CLIENTS & FORK (PÈRE) // ========================================================================= diff --git a/shared/event_handler.c b/shared/event_handler.c index 7bb82bf..3bcc728 100644 --- a/shared/event_handler.c +++ b/shared/event_handler.c @@ -2,7 +2,7 @@ void tryCallFunction(int socket, char** events, cmd_handler_func functions[], int size, char* input) { - // Logique de Parsing et de Dispatch (comme précédemment) + // Logique de Parsing et de Dispatch (comme précédemment) char* buffer_copy = strdup(input); if (!buffer_copy) return; diff --git a/shared/socket.c b/shared/socket.c new file mode 100644 index 0000000..3447b76 --- /dev/null +++ b/shared/socket.c @@ -0,0 +1,13 @@ +#include "socket.h" + +void envoyer_message(int sock, const char *msg) { + write(sock, msg, strlen(msg)); + write(sock, "\n", 1); +} + +void envoyer_ipc(int pipe_fd, const char *msg) { + if (write(pipe_fd, msg, strlen(msg)) < 0) { + perror("Erreur ecriture IPC"); + } + write(pipe_fd, "\n", 1); // Délimiteur +} \ No newline at end of file diff --git a/shared/socket.h b/shared/socket.h new file mode 100644 index 0000000..bcda9ab --- /dev/null +++ b/shared/socket.h @@ -0,0 +1,6 @@ +#include +#include +#include + +void envoyer_message(int sock, const char *msg); +void envoyer_ipc(int pipe_fd, const char *msg); \ No newline at end of file From a07f4c30f36b365b692a391b6da99d9b4fb0d81c Mon Sep 17 00:00:00 2001 From: hoverwars Date: Mon, 13 Oct 2025 22:14:38 +0200 Subject: [PATCH 2/4] [FEAT] Clear child process work --- server/models.h | 2 +- server/server.c | 51 +++---------------------------- shared/awale.c | 3 +- shared/event_handler.c | 69 ++++++++++++++++++++++-------------------- shared/event_handler.h | 17 ++++++++++- 5 files changed, 59 insertions(+), 83 deletions(-) diff --git a/server/models.h b/server/models.h index 14f4d4b..f54d0f1 100644 --- a/server/models.h +++ b/server/models.h @@ -9,7 +9,7 @@ #define MAX_BUFFER 256 // Structure pour stocker les informations des joueurs actifs, qui sont connectés au serveur. -typedef struct { +typedef struct JoueurActif { char pseudo[MAX_PSEUDO_LEN]; pid_t pid; int pipe_p_to_f; // Descripteur d'écriture du PÈRE (pour envoyer au FILS) diff --git a/server/server.c b/server/server.c index afb27f1..6707ea4 100644 --- a/server/server.c +++ b/server/server.c @@ -366,53 +366,10 @@ void handle_client(int newsockfd, const char *pseudo, const char *ip_client, int int nbytes = read(newsockfd, buffer, sizeof(buffer) - 1); if (nbytes <= 0) break; // Client déconnecté buffer[nbytes] = '\0'; - - // Logique de Parsing et de Dispatch (comme précédemment) - char* buffer_copy = strdup(buffer); - if (!buffer_copy) break; - char* raw_tokens[MAX_TOKENS]; - int raw_token_count = 0; - char* token = strtok(buffer_copy, " \n\r\t"); - while (token != NULL && raw_token_count < MAX_TOKENS) { - raw_tokens[raw_token_count++] = token; - token = strtok(NULL, " \n\r\t"); - } - - if (raw_token_count > 0) { - int function_index = -1; - for (int i = 0; tableau_evenements[i] != NULL; i++) { - if (strcmp(tableau_evenements[i], raw_tokens[0]) == 0) { - function_index = i; - break; - } - } - - if (function_index >= 0 && tableau_fonctions[function_index] != NULL) { - - // Préparation des arguments pour la fonction de gestion - char* final_tokens[MAX_TOKENS + 1]; - int final_argc = raw_token_count + 1; - - final_tokens[0] = raw_tokens[0]; - final_tokens[1] = (char*)pseudo; // PSEUDO LOCAL EN argv[1] - for(int i = 1; i < raw_token_count; i++) { - final_tokens[i+1] = raw_tokens[i]; - } - final_tokens[final_argc] = NULL; - - if (strcmp(final_tokens[0], "QUIT") == 0) { - free(buffer_copy); - handle_quit(newsockfd, final_argc, final_tokens, pipe_write_to_p); - break; - } - - // Appel avec (socket, argc, argv, pipe_write_to_p) - tableau_fonctions[function_index](newsockfd, final_argc, final_tokens, pipe_write_to_p); - } else { - envoyer_message(newsockfd, "ERREUR_COMMANDE Commande non reconnue."); - } - } - free(buffer_copy); + + // Propagate the received content to the parent. We already check that the buffer contains data. + // The parent process will handle game events. + envoyer_ipc(pipe_write_to_p, buffer); } // --- 2. GESTION DES NOTIFICATIONS PÈRE -> FILS (pipe_read_from_p) --- diff --git a/shared/awale.c b/shared/awale.c index a09e0e1..9e90c72 100644 --- a/shared/awale.c +++ b/shared/awale.c @@ -26,8 +26,7 @@ static bool is_camp_vide(const AwalePartie *partie, int joueur) { * @param trou_idx L'index du trou a jouer (0 a 5). * @param graines_capturable Pointeur ou stocker le nombre de graines qui seraient capturees. */ -static void simuler_coup(const AwalePartie *partie_src, AwalePartie *partie_simul, - int trou_idx, int *graines_capturable) +static void simuler_coup(const AwalePartie *partie_src, AwalePartie *partie_simul, int trou_idx, int *graines_capturable) { // Copie de l'etat source pour la simulation memcpy(partie_simul, partie_src, sizeof(AwalePartie)); diff --git a/shared/event_handler.c b/shared/event_handler.c index 3bcc728..8efdce9 100644 --- a/shared/event_handler.c +++ b/shared/event_handler.c @@ -1,11 +1,36 @@ #include "event_handler.h" void tryCallFunction(int socket, char** events, cmd_handler_func functions[], int size, char* input) +{ + SocketParams socketParams = extractArguments(input); + + if (socketParams.argc > 0) { + int function_index = -1; + for (int i = 0; events[i] != NULL; i++) { + if (strcmp(events[i], socketParams.argv[0]) == 0) { + function_index = i; + break; + } + } + + if (function_index >= 0 && functions[function_index] != NULL) + { + // Actually, the pipe is not provided. + functions[function_index](socket, socketParams.argc, socketParams.argv, 0); + } + else + { + printf("Erreur: Impossible de trouver une fonction à appeler pour la directive %s", socketParams.argv[0]); + } + } +} + +SocketParams extractArguments(char* input) { // Logique de Parsing et de Dispatch (comme précédemment) char* buffer_copy = strdup(input); if (!buffer_copy) return; - + char* raw_tokens[ARGS_MAX_SIZE]; int raw_token_count = 0; char* token = strtok(buffer_copy, " \n\r\t"); @@ -15,37 +40,17 @@ void tryCallFunction(int socket, char** events, cmd_handler_func functions[], in token = strtok(NULL, " \n\r\t"); } - if (raw_token_count > 0) { - int function_index = -1; - for (int i = 0; events[i] != NULL; i++) { - if (strcmp(events[i], raw_tokens[0]) == 0) { - function_index = i; - break; - } - } - - if (function_index >= 0 && functions[function_index] != NULL) { - - // Préparation des arguments pour la fonction de gestion - // char* final_tokens[MAX_TOKENS + 1]; - // int final_argc = raw_token_count + 1; - - raw_tokens[raw_token_count] = NULL; - - /*final_tokens[0] = raw_tokens[0]; - final_tokens[1] = (char*)pseudo; // PSEUDO LOCAL EN argv[1] - for(int i = 1; i < raw_token_count; i++) { - final_tokens[i+1] = raw_tokens[i]; - } - final_tokens[final_argc] = NULL;*/ - - - // Actually, the pipe is not provided. - functions[function_index](socket, raw_token_count, raw_tokens, 0); - } - /*else { - envoyer_message(socket, "ERREUR_COMMANDE Commande non reconnue."); - }*/ + if (raw_token_count > 0) + { + raw_tokens[raw_token_count] = NULL; } + free(buffer_copy); + + struct SocketParams params = { + raw_token_count, + raw_tokens + }; + + return params; } \ No newline at end of file diff --git a/shared/event_handler.h b/shared/event_handler.h index 31a7db2..52f7522 100644 --- a/shared/event_handler.h +++ b/shared/event_handler.h @@ -1,3 +1,6 @@ +#ifndef EVENT_HANDLER_C +#define EVENT_HANDLER_C + #include #include #include @@ -7,9 +10,21 @@ typedef void (*cmd_handler_func)(int, int, char**, int); +typedef struct SocketParams { + int argc; + char** argv; +} SocketParams; + /** * Try to find the function associated to the event list, based on an event * received from the server. * Call it using known parameters. */ -void tryCallFunction(int socket, char** events, cmd_handler_func functions[], int size, char* input); \ No newline at end of file +void tryCallFunction(int socket, char** events, cmd_handler_func functions[], int size, char* input); + +/** + * From a string input, split words separated by spaces and return a structure representing the words + */ +SocketParams extractArguments(char* input); + +#endif // EVENT_HANDLER_C \ No newline at end of file From 1ccfc419975fc23069cca067a03c70b893cb3504 Mon Sep 17 00:00:00 2001 From: hoverwars Date: Mon, 13 Oct 2025 23:01:29 +0200 Subject: [PATCH 3/4] [FIX] Wrong memory free --- shared/event_handler.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/shared/event_handler.c b/shared/event_handler.c index 8efdce9..78a0130 100644 --- a/shared/event_handler.c +++ b/shared/event_handler.c @@ -20,7 +20,13 @@ void tryCallFunction(int socket, char** events, cmd_handler_func functions[], in } else { - printf("Erreur: Impossible de trouver une fonction à appeler pour la directive %s", socketParams.argv[0]); + printf("Erreur: Impossible de trouver une fonction à appeler pour la directive %s\n", socketParams.argv[0]); + printf("Original input: %s\n", input); + printf("Directives disponibles: \n"); + for (int i = 0; i < socketParams.argc; i++) + { + printf("%s\n", events[i]); + } } } } @@ -35,7 +41,8 @@ SocketParams extractArguments(char* input) int raw_token_count = 0; char* token = strtok(buffer_copy, " \n\r\t"); - while (token != NULL && raw_token_count < ARGS_MAX_SIZE) { + while (token != NULL && raw_token_count < ARGS_MAX_SIZE) + { raw_tokens[raw_token_count++] = token; token = strtok(NULL, " \n\r\t"); } @@ -44,9 +51,9 @@ SocketParams extractArguments(char* input) { raw_tokens[raw_token_count] = NULL; } - - free(buffer_copy); - + + //free(buffer_copy) Cannot do it at the moment. + struct SocketParams params = { raw_token_count, raw_tokens From 6b2505e2e3f85ad12d03c6626c74c2c19362a1c5 Mon Sep 17 00:00:00 2001 From: hoverwars Date: Tue, 14 Oct 2025 01:06:36 +0200 Subject: [PATCH 4/4] [FIX] Working on --- client/client.c | 66 +++++++------- server/chat.c | 7 ++ server/defi.c | 40 ++++++++- server/events.h | 12 ++- server/joueur.h | 0 server/matches.c | 60 +++++++++++++ server/matches.h | 26 ++++++ server/models.h | 7 ++ server/server.c | 191 ++++++++++++----------------------------- shared/event_handler.c | 11 ++- shared/event_handler.h | 2 +- 11 files changed, 249 insertions(+), 173 deletions(-) create mode 100644 server/chat.c delete mode 100644 server/joueur.h create mode 100644 server/matches.c create mode 100644 server/matches.h diff --git a/client/client.c b/client/client.c index b5a201c..acdb831 100644 --- a/client/client.c +++ b/client/client.c @@ -363,39 +363,41 @@ int main(int argc, char *argv[]) continue; } - // Raccourci: si l'utilisateur tape juste un nombre 0..5, traiter comme PLAY/MOVE -if (tk0 && !tk1) { - int numeric = 1; - for (const char* p = tk0; *p; ++p) { - if (!isdigit((unsigned char)*p)) { numeric = 0; break; } - } - if (numeric) { - if (!g_en_partie) { - printf("[CLIENT] Vous n'etes pas en partie. Ignorer entree numerique.\n"); - } else { - int trou = atoi(tk0); - if (trou < 0 || trou >= NB_TROUS_CAMP) { - printf("[CLIENT] Trou invalide (0..5).\n"); - } else if (g_partie.joueur_courant != g_role_local) { - printf("[CLIENT] Ce n'est pas votre tour.\n"); - } else if (!awale_verifier_legalite(&g_partie, trou)) { - printf("[CLIENT] Coup illegal localement.\n"); - } else if (!awale_jouer_coup(&g_partie, trou)) { - printf("[CLIENT] Echec lors de l'application locale du coup.\n"); - } else { - printf("\n=== Votre coup joue localement (trou %d) ===\n", trou); - awale_afficher_plateau(&g_partie); - - char out[32]; - int len = snprintf(out, sizeof(out), "MOVE %d", trou); - nbytes = write(sockfd, out, len); - write(sockfd, "\n", 1); - if (nbytes < 0) erreur("Erreur ecriture socket (MOVE)"); + // Raccourci: si l'utilisateur tape juste un nombre 0..5, traiter comme PLAY/MOVE + if (tk0 && !tk1) { + int numeric = 1; + for (const char* p = tk0; *p; ++p) { + if (!isdigit((unsigned char)*p)) { numeric = 0; break; } + } + if (numeric) { + if (!g_en_partie) { + printf("[CLIENT] Vous n'etes pas en partie. Ignorer entree numerique.\n"); + } + else { + int trou = atoi(tk0); + if (trou < 0 || trou >= NB_TROUS_CAMP) { + printf("[CLIENT] Trou invalide (0..5).\n"); + } else if (g_partie.joueur_courant != g_role_local) { + printf("[CLIENT] Ce n'est pas votre tour.\n"); + } else if (!awale_verifier_legalite(&g_partie, trou)) { + printf("[CLIENT] Coup illegal localement.\n"); + } else if (!awale_jouer_coup(&g_partie, trou)) { + printf("[CLIENT] Echec lors de l'application locale du coup.\n"); + } else { + printf("\n=== Votre coup joue localement (trou %d) ===\n", trou); + awale_afficher_plateau(&g_partie); + + char out[32]; + int len = snprintf(out, sizeof(out), "MOVE %d", trou); + nbytes = write(sockfd, out, len); + write(sockfd, "\n", 1); + if (nbytes < 0) erreur("Erreur ecriture socket (MOVE)"); + } + } + continue; + } } - } - continue; - } -} + // Envoi par défaut tel quel au serveur (DEFI, ACCEPT, REFUSE, QUIT, etc.) int cmd_len = strlen(buffer); nbytes = write(sockfd, buffer, cmd_len); diff --git a/server/chat.c b/server/chat.c new file mode 100644 index 0000000..733b206 --- /dev/null +++ b/server/chat.c @@ -0,0 +1,7 @@ +#include "events.h" +#include "matches.h" + +void handle_message(int sock, int argc, char** argv, int pipe_write_to_p) +{ + +} diff --git a/server/defi.c b/server/defi.c index aec8302..1841533 100644 --- a/server/defi.c +++ b/server/defi.c @@ -1,8 +1,7 @@ #include "events.h" -void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p) { +/*void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p) { // argv[0] = "DEFI", argv[1] = pseudo_local, argv[2] = adversaire - if (argc < 3) { envoyer_message(sock, "ERREUR_PROTOCOLE Commande DEFI incomplete. Usage: DEFI "); return; @@ -24,6 +23,43 @@ void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p) { printf("FIL (%s): Defi envoye au PERE pour repartition vers %s.\n", pseudo_local, adversaire); envoyer_message(sock, "DEFI_ENVOYE En attente de la reponse de l'adversaire..."); +}*/ + +void handle_defi(int sock, int argc, char** argv, int pipe_write_to_p) +{ + const char *defiante = argv[1]; + const char *adversaire = argv[2]; + + printf("%s %s\n", defiante, adversaire); + int idx_defiante = trouver_index_joueur(defiante); + int idx_adversaire = trouver_index_joueur(adversaire); + + if (idx_adversaire == -1) { + // Le joueur ciblé n'est pas actif + if (idx_defiante != -1) { + char notif[MAX_BUFFER]; + snprintf(notif, MAX_BUFFER, "ERREUR_DEFI Le joueur %s n'est pas actif.", adversaire); + envoyer_ipc(joueurs_actifs[idx_defiante].pipe_p_to_f, notif); + } + } else if (idx_defiante != -1 && joueurs_actifs[idx_defiante].en_partie) { + // Le défieur est déjà en partie + char notif[MAX_BUFFER]; + snprintf(notif, MAX_BUFFER, "ERREUR_DEFI Vous etes deja en partie."); + envoyer_ipc(joueurs_actifs[idx_defiante].pipe_p_to_f, notif); + } else if (joueurs_actifs[idx_adversaire].en_partie) { + // Le joueur défié est occupé + if (idx_defiante != -1) { + char notif[MAX_BUFFER]; + snprintf(notif, MAX_BUFFER, "ERREUR_DEFI Le joueur %s est deja en partie.", adversaire); + envoyer_ipc(joueurs_actifs[idx_defiante].pipe_p_to_f, notif); + } + } else { + // Relayer le défi au fils de l'adversaire + char notif[MAX_BUFFER]; + snprintf(notif, MAX_BUFFER, "DEFI_RECU %s", defiante); + envoyer_ipc(joueurs_actifs[idx_adversaire].pipe_p_to_f, notif); + printf("PÈRE: Défi de %s relayé à %s.\n", defiante, adversaire); + } } void handle_refuse(int sock, int argc, char** argv, int pipe_write_to_p) { diff --git a/server/events.h b/server/events.h index b2331aa..b992e04 100644 --- a/server/events.h +++ b/server/events.h @@ -1,6 +1,10 @@ +#ifndef EVENTS_H +#define EVENTS_H + #include #include #include +#include "matches.h" #include "models.h" #include "../shared/socket.h" @@ -12,4 +16,10 @@ void handle_accept(int sock, int argc, char** argv, int pipe_write_to_p); // Events related to game itself void handle_move(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p); \ No newline at end of file +void handle_quit(int sock, int argc, char** argv, int pipe_write_to_p); + +// Events related to communication between players + +void handle_message(int sock, int argc, char** argv, int pipe_write_to_p); + +#endif \ No newline at end of file diff --git a/server/joueur.h b/server/joueur.h deleted file mode 100644 index e69de29..0000000 diff --git a/server/matches.c b/server/matches.c new file mode 100644 index 0000000..e205a3e --- /dev/null +++ b/server/matches.c @@ -0,0 +1,60 @@ +#include "matches.h" + +int trouver_index_joueur(const char* pseudo) +{ + for (int i = 0; i < nb_joueurs_actifs; i++) + { + if (strcmp(joueurs_actifs[i].pseudo, pseudo) == 0) + { + return i; + } + } + + return -1; +} + +int trouver_match_index(const char* sud, const char* nord) { + for (int i = 0; i < nb_matches; i++) { + if (matches[i].actif && + strcmp(matches[i].sud, sud) == 0 && + strcmp(matches[i].nord, nord) == 0) { + return i; + } + } + return -1; +} + +int creer_match(const char* sud, const char* nord) { + int idx = trouver_match_index(sud, nord); + if (idx != -1) { + // Déjà créé et actif + return idx; + } + + // Tenter de réutiliser un slot inactif + int free_idx = -1; + for (int i = 0; i < nb_matches; i++) { + if (!matches[i].actif) { + free_idx = i; + break; + } + } + + // Sinon, allouer un nouveau slot si possible + if (free_idx == -1) { + if (nb_matches >= MAX_MATCHES) { + return -1; + } + free_idx = nb_matches++; + } + + // Initialiser le match + strncpy(matches[free_idx].sud, sud, MAX_PSEUDO_LEN - 1); + matches[free_idx].sud[MAX_PSEUDO_LEN - 1] = '\0'; + strncpy(matches[free_idx].nord, nord, MAX_PSEUDO_LEN - 1); + matches[free_idx].nord[MAX_PSEUDO_LEN - 1] = '\0'; + + awale_init(&matches[free_idx].partie); // Initialise partie locale serveur + matches[free_idx].actif = 1; + return free_idx; +} diff --git a/server/matches.h b/server/matches.h new file mode 100644 index 0000000..9774791 --- /dev/null +++ b/server/matches.h @@ -0,0 +1,26 @@ +#ifndef JOUEURS_H +#define JOUEURS_H + +#include +#include "models.h" + +#define MAX_JOUEURS 100 +#define MAX_MATCHES 100 + +/** + * Trouver un joueur actif à l'aide de son pseudo + */ +int trouver_index_joueur(const char* pseudo); + +/** + * Trouver un match entre 2 joueurs actifs + */ +int trouver_match_index(const char* sud, const char* nord); + +/** + * Creer un match entre 2 joueurs. Retourne l'index du match. + * Si le match existe déjà entre ces 2 joueurs, la fonction retourne l'index du match courant. + */ +int creer_match(const char* sud, const char* nord); + +#endif \ No newline at end of file diff --git a/server/models.h b/server/models.h index f54d0f1..5aae43c 100644 --- a/server/models.h +++ b/server/models.h @@ -8,6 +8,7 @@ #define MAX_PSEUDO_LEN 32 #define MAX_BUFFER 256 + // Structure pour stocker les informations des joueurs actifs, qui sont connectés au serveur. typedef struct JoueurActif { char pseudo[MAX_PSEUDO_LEN]; @@ -28,4 +29,10 @@ typedef struct { int actif; // 1 si match actif } Match; +extern JoueurActif joueurs_actifs[]; +extern int nb_joueurs_actifs; + +extern Match matches[]; +extern int nb_matches; + #endif \ No newline at end of file diff --git a/server/server.c b/server/server.c index 6707ea4..f8bfef1 100644 --- a/server/server.c +++ b/server/server.c @@ -15,32 +15,30 @@ #include #include // Pour fcntl et O_NONBLOCK #include "events.h" +#include "matches.h" #include "models.h" #include "../shared/event_handler.h" #include "../shared/socket.h" // --- Constantes et structures --- -#define MAX_JOUEURS 100 #define MAX_TOKENS 12 -#define MAX_MATCHES 100 -void handle_refuse(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_msg(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_brc(int sock, int argc, char** argv, int pipe_write_to_p); -void handle_surr(int sock, int argc, char** argv, int pipe_write_to_p); - -// Store active players +// Define global variables, stored in events.h JoueurActif joueurs_actifs[MAX_JOUEURS]; int nb_joueurs_actifs = 0; -// Store active matchs Match matches[MAX_MATCHES]; int nb_matches = 0; +void handle_refuse(int sock, int argc, char** argv, int pipe_write_to_p); +void handle_msg(int sock, int argc, char** argv, int pipe_write_to_p); +void handle_brc(int sock, int argc, char** argv, int pipe_write_to_p); +void handle_surr(int sock, int argc, char** argv, int pipe_write_to_p); + // Information related to event handling. The client send events to the server that handle them by matching one event label with a reaction function. -char* tableau_evenements[] = {"DEFI", "QUIT", "ACCEPT", "REFUSE", "MOVE", "MSG", "BRC", "SURR", NULL}; +char* events[] = {"DEFI", "QUIT", "ACCEPT", "REFUSE", "MOVE", "MSG", "BRC", "SURR", NULL}; -cmd_handler_func tableau_fonctions[] = { +cmd_handler_func functions[] = { handle_defi, handle_quit, handle_accept, @@ -52,53 +50,9 @@ cmd_handler_func tableau_fonctions[] = { NULL }; -// ================== Gestion des Parties côté Serveur (PÈRE) ================== +int eventCount = 8; -int trouver_match_index(const char* sud, const char* nord) { - for (int i = 0; i < nb_matches; i++) { - if (matches[i].actif && - strcmp(matches[i].sud, sud) == 0 && - strcmp(matches[i].nord, nord) == 0) { - return i; - } - } - return -1; -} - -int creer_match(const char* sud, const char* nord) { - int idx = trouver_match_index(sud, nord); - if (idx != -1) { - // Déjà créé et actif - return idx; - } - - // Tenter de réutiliser un slot inactif - int free_idx = -1; - for (int i = 0; i < nb_matches; i++) { - if (!matches[i].actif) { - free_idx = i; - break; - } - } - - // Sinon, allouer un nouveau slot si possible - if (free_idx == -1) { - if (nb_matches >= MAX_MATCHES) { - return -1; - } - free_idx = nb_matches++; - } - - // Initialiser le match - strncpy(matches[free_idx].sud, sud, MAX_PSEUDO_LEN - 1); - matches[free_idx].sud[MAX_PSEUDO_LEN - 1] = '\0'; - strncpy(matches[free_idx].nord, nord, MAX_PSEUDO_LEN - 1); - matches[free_idx].nord[MAX_PSEUDO_LEN - 1] = '\0'; - - awale_init(&matches[free_idx].partie); // Initialise partie locale serveur - matches[free_idx].actif = 1; - return free_idx; -} +// ================== Gestion des Parties côté Serveur (PÈRE) ================== // --- Prototypes des fonctions --- @@ -106,8 +60,6 @@ int ajouter_pseudo(const char *pseudo, pid_t fils_pid, int p_to_f_fd, int f_to_p void retirer_pseudo(const char *pseudo); void envoyer_message(int sock, const char *msg); -int trouver_index_joueur(const char *pseudo); - void handle_inscription_and_fork(int sockfd_ecoute, int newsockfd, const struct sockaddr_in *cli_addr); // Ajout des descripteurs de pipe pour handle_client void handle_client(int newsockfd, const char *pseudo, const char *ip_client, int pipe_read_from_p, int pipe_write_to_p); @@ -131,14 +83,7 @@ void sigchld_handler(int s) // LOGIQUE DE GESTION DES PSEUDOS (PÈRE) // ========================================================================= -int trouver_index_joueur(const char *pseudo) { - for (int i = 0; i < nb_joueurs_actifs; i++) { - if (strcmp(joueurs_actifs[i].pseudo, pseudo) == 0) { - return i; - } - } - return -1; -} + int ajouter_pseudo(const char *pseudo, pid_t fils_pid, int p_to_f_fd, int f_to_p_fd) { if (nb_joueurs_actifs >= MAX_JOUEURS) return 2; @@ -513,6 +458,17 @@ void gerer_ipc_fils(int sock_ecoute) { char *newline = strchr(ipc_buffer, '\n'); if (newline) *newline = '\0'; + // Handle directive read from pipe stream. + printf("buffer: %s\n", ipc_buffer); + tryCallFunction( + joueurs_actifs[i].pipe_f_to_p, + events, + functions, + eventCount, + ipc_buffer + ); + + printf("PÈRE: Message IPC de %s: %s\n", joueurs_actifs[i].pseudo, ipc_buffer); // Gestion prioritaire des messages de chat (préserve les espaces du contenu) @@ -568,41 +524,8 @@ void gerer_ipc_fils(int sock_ecoute) { char *commande = strtok(ipc_buffer, " "); char *arg1 = strtok(NULL, " "); char *arg2 = strtok(NULL, " "); - - if (commande && strcmp(commande, "DEFI") == 0 && arg1 && arg2) { - const char *defiante = arg1; - const char *adversaire = arg2; - - int idx_defiante = trouver_index_joueur(defiante); - int idx_adversaire = trouver_index_joueur(adversaire); - - if (idx_adversaire == -1) { - // Le joueur ciblé n'est pas actif - if (idx_defiante != -1) { - char notif[MAX_BUFFER]; - snprintf(notif, MAX_BUFFER, "ERREUR_DEFI Le joueur %s n'est pas actif.", adversaire); - envoyer_ipc(joueurs_actifs[idx_defiante].pipe_p_to_f, notif); - } - } else if (idx_defiante != -1 && joueurs_actifs[idx_defiante].en_partie) { - // Le défieur est déjà en partie - char notif[MAX_BUFFER]; - snprintf(notif, MAX_BUFFER, "ERREUR_DEFI Vous etes deja en partie."); - envoyer_ipc(joueurs_actifs[idx_defiante].pipe_p_to_f, notif); - } else if (joueurs_actifs[idx_adversaire].en_partie) { - // Le joueur défié est occupé - if (idx_defiante != -1) { - char notif[MAX_BUFFER]; - snprintf(notif, MAX_BUFFER, "ERREUR_DEFI Le joueur %s est deja en partie.", adversaire); - envoyer_ipc(joueurs_actifs[idx_defiante].pipe_p_to_f, notif); - } - } else { - // Relayer le défi au fils de l'adversaire - char notif[MAX_BUFFER]; - snprintf(notif, MAX_BUFFER, "DEFI_RECU %s", defiante); - envoyer_ipc(joueurs_actifs[idx_adversaire].pipe_p_to_f, notif); - printf("PÈRE: Défi de %s relayé à %s.\n", defiante, adversaire); - } - } else if (commande && strcmp(commande, "REFUSE") == 0 && arg1 && arg2) { + + if (commande && strcmp(commande, "REFUSE") == 0 && arg1 && arg2) { const char *defie = arg1; const char *defiante = arg2; @@ -868,47 +791,47 @@ void gerer_ipc_fils(int sock_ecoute) { int main(int argc, char** argv) { - int sockfd; - struct sockaddr_in serv_addr; + int sockfd; + struct sockaddr_in serv_addr; - if (argc != 2) { - fprintf(stderr, "Usage: %s port\n", argv[0]); - exit(1); - } + if (argc != 2) { + fprintf(stderr, "Usage: %s port\n", argv[0]); + exit(1); + } - printf("Serveur (concurrent) démarré...\n"); + printf("Serveur (concurrent) démarré...\n"); - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) { perror("Erreur ouverture socket"); exit(1); } + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { perror("Erreur ouverture socket"); exit(1); } - int optval = 1; - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { - perror("Erreur setsockopt (SO_REUSEADDR)"); - } + int optval = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { + perror("Erreur setsockopt (SO_REUSEADDR)"); + } - bzero((char*) &serv_addr, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); - serv_addr.sin_port = htons(atoi(argv[1])); + bzero((char*) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); + serv_addr.sin_port = htons(atoi(argv[1])); - if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { - perror("Erreur bind"); - exit(1); - } + if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { + perror("Erreur bind"); + exit(1); + } - listen(sockfd, 5); + listen(sockfd, 5); - struct sigaction sa; - sa.sa_handler = sigchld_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } + struct sigaction sa; + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); } - printf("Serveur prêt. En attente de connexions sur le port %s...\n", argv[1]); + printf("Serveur prêt. En attente de connexions sur le port %s...\n", argv[1]); - // Boucle principale utilisant select() pour gérer les nouvelles connexions et l'IPC - gerer_ipc_fils(sockfd); + // Boucle principale utilisant select() pour gérer les nouvelles connexions et l'IPC + gerer_ipc_fils(sockfd); - close(sockfd); - return 0; + close(sockfd); + return 0; } \ No newline at end of file diff --git a/shared/event_handler.c b/shared/event_handler.c index 78a0130..b132d30 100644 --- a/shared/event_handler.c +++ b/shared/event_handler.c @@ -1,6 +1,6 @@ #include "event_handler.h" -void tryCallFunction(int socket, char** events, cmd_handler_func functions[], int size, char* input) +void tryCallFunction(int fd, char** events, cmd_handler_func functions[], int size, char* input) { SocketParams socketParams = extractArguments(input); @@ -16,7 +16,8 @@ void tryCallFunction(int socket, char** events, cmd_handler_func functions[], in if (function_index >= 0 && functions[function_index] != NULL) { // Actually, the pipe is not provided. - functions[function_index](socket, socketParams.argc, socketParams.argv, 0); + printf("Appel d'une directive: %s\n", events[function_index]); + functions[function_index](fd, socketParams.argc, socketParams.argv, 0); } else { @@ -35,7 +36,11 @@ SocketParams extractArguments(char* input) { // Logique de Parsing et de Dispatch (comme précédemment) char* buffer_copy = strdup(input); - if (!buffer_copy) return; + if (!buffer_copy) + { + struct SocketParams emptyParams = { 0, NULL }; + return emptyParams; + } char* raw_tokens[ARGS_MAX_SIZE]; int raw_token_count = 0; diff --git a/shared/event_handler.h b/shared/event_handler.h index 52f7522..2640c4a 100644 --- a/shared/event_handler.h +++ b/shared/event_handler.h @@ -20,7 +20,7 @@ typedef struct SocketParams { * received from the server. * Call it using known parameters. */ -void tryCallFunction(int socket, char** events, cmd_handler_func functions[], int size, char* input); +void tryCallFunction(int fd, char** events, cmd_handler_func functions[], int size, char* input); /** * From a string input, split words separated by spaces and return a structure representing the words