#include #include #include #include #include #include "server_code_etudiant.h" client_t *clients[MAX_CLIENTS]; struct hash_table ht; /* Calcule le hash d'une cle. La valeur retournee est un entier entre 0 et 15. */ int ht_hash(char key[NAME_MAX_LENGTH]) { int hash=0; for(int i=0; i dans la hashtable. * Si la cle key existe deja, sa valeur est mise a jour. */ void ht_insert(char key[NAME_MAX_LENGTH], client_t* value) { int hash = ht_hash(key); /* TODO */ } /* Supprime le struct bucket dont la cle vaut key */ void ht_remove(char key[NAME_MAX_LENGTH]) { int hash = ht_hash(key); struct bucket* b = ht.buckets[hash]; /* TODO */ } /* Enregistre la liste des utilisateurs dans le fichier filename */ void ht_dump(char* filename) { /* TODO */ } /* Envoie a client la liste des utilisateurs contenue dans le fichier filename */ void ht_load(client_t* client, char* filename) { /* TODO */ } /* Strip CRLF */ void strip_newline(char *s) { while(*s != '\0'){ if(*s == '\r' || *s == '\n'){ *s = '\0'; } s++; } } client_t *get_client_from_fd(int fd) { /* l'implementation est cachee car inutile pour ce CF */ return NULL; } client_t *get_client_from_name(char* name) { struct bucket* b = ht_search(name); if(b) { return &b->value; } return NULL; } void server_init() { } /* Add client to queue */ void queue_add(client_t *cl){ ht_insert(cl->name, cl); } /* Delete client from queue */ void queue_delete(client_t *client){ ht_remove(client->name); } /* Send a message to a client */ void send_message(char *s, client_t *client){ fwrite(s, sizeof(char), strlen(s), client->client_conn); } /* Send message to all clients */ void send_message_all(char *s){ /* l'implementation est cachee car inutile pour ce CF */ } void assign_default_name(client_t* cli) { sprintf(cli->name, "Anonymous_%d", cli->uid); } /* this function is called when a client connects to the server */ void say_hello(client_t *cli) { char buff_out[1024]; /* choose a default name */ assign_default_name(cli); sprintf(buff_out, "* %s joins the chatroom\n", cli->name); send_message_all(buff_out); } void process_cmd_msg(client_t*client, char*param) { char*dest = strsep(¶m, " "); if(!dest){ send_message("* to who ?\n", client); return; } char buffer[1024]; sprintf(buffer, "[PM][%s --> %s] %s\n", client->name, dest, param); client_t* to = get_client_from_name(dest); if(!to ){ send_message("* %s does not exist!\n", client); } else { send_message(buffer, to); send_message(buffer, client); } } void process_cmd_help(client_t* client) { char buff_out[1024]; sprintf(buff_out, "/help Show help\n"); strcat(buff_out, "/msg Send private message\n"); strcat(buff_out, "/ping Server test\n"); strcat(buff_out, "/dump_users Write the user lists to disk\n"); strcat(buff_out, "/show_users Show the content of a file\n"); strcat(buff_out, "/quit Quit chatroom\n"); send_message(buff_out, client); } void process_cmd_ping(client_t* client, char* param) { send_message("* pong\n", client); } void process_cmd_dump_users(client_t* client, char* param) { char*filename = strsep(¶m, " "); if(!filename){ send_message("* where ?\n", client); return; } ht_dump(filename); char buffer[1024]; sprintf(buffer, "* user list saved to %s\n", filename); send_message(buffer, client); } void process_cmd_show_users(client_t* client, char* param) { char*filename = strsep(¶m, " "); if(!filename){ send_message("* which file ?\n", client); return; } ht_load(client, filename); } void handle_incoming_cmd(client_t *cli) { char buff_out[1024]; char buff_in[1024]; if(fgets(buff_in, 1024*sizeof(char), cli->client_conn) == 0) { if(!feof(cli->client_conn)) { perror("read failed"); abort(); } else { printf("Client %s disconnected\n", cli->name); cli->fd = -1; queue_delete(cli); return; } } strip_newline(buff_in); /* Ignore empty buffer */ if(!strlen(buff_in)){ printf("Empty message\n"); } /* Special options */ char *cmd_line = buff_in; if(buff_in[0] == '/'){ char *command; command = strsep(&cmd_line," "); if(!strcmp(command, "/quit")){ return; } else if(!strcmp(command, "/ping")) { process_cmd_ping(cli, cmd_line); } else if(!strcmp(command, "/msg")) { process_cmd_msg(cli, cmd_line); } else if(!strcmp(command, "/dump_users")) { process_cmd_dump_users(cli, cmd_line); } else if(!strcmp(command, "/show_users")) { process_cmd_show_users(cli, cmd_line); } else { /* /help or unknown command */ process_cmd_help(cli); } }else{ /* Send message */ sprintf(buff_out, "[%s] %s\n", cli->name, cmd_line); send_message_all(buff_out); } }