diff options
Diffstat (limited to 'client.c')
-rw-r--r-- | client.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/client.c b/client.c new file mode 100644 index 0000000..2099862 --- /dev/null +++ b/client.c @@ -0,0 +1,102 @@ +#include "client.h" +#include "chatroom.h" +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <pthread.h> +#include <arpa/inet.h> + +extern client_t *clients[]; +extern pthread_mutex_t clients_mutex; + +void send_to_client(int sock, const char *msg) { + send(sock, msg, strlen(msg), 0); +} + +void broadcast_message(const char *message, int sender_sock) { + pthread_mutex_lock(&clients_mutex); + + client_t *sender = NULL; + for (int i = 0; i < 10; i++) { + if (clients[i] && clients[i]->socket == sender_sock) { + sender = clients[i]; + break; + } + } + + if (sender == NULL || strlen(sender->room) == 0) { + pthread_mutex_unlock(&clients_mutex); + return; + } + + for (int i = 0; i < 10; i++) { + if (clients[i] && clients[i]->socket != sender_sock && + strcmp(clients[i]->room, sender->room) == 0) { + send_to_client(clients[i]->socket, message); + } + } + + pthread_mutex_unlock(&clients_mutex); +} + +void *handle_client(void *arg) { + client_t *cli = (client_t *)arg; + char buffer[BUFFER_SIZE]; + int bytes; + + while ((bytes = recv(cli->socket, buffer, BUFFER_SIZE - 1, 0)) > 0) { + buffer[bytes] = '\0'; + + if (strncmp(buffer, "/join ", 6) == 0) { + char room[50]; + sscanf(buffer + 6, "%s", room); + if (join_chatroom(room, cli)) { + char msg[128]; + snprintf(msg, sizeof(msg), "You joined '%s'\n", room); + send_to_client(cli->socket, msg); + } else { + send_to_client(cli->socket, "Room does not exist.\n"); + } + } + else if (strncmp(buffer, "/list", 5) == 0) { + print_chatroom_list(cli->socket); + } + else if (strncmp(buffer, "/users", 6) == 0) { + pthread_mutex_lock(&clients_mutex); + int count = 0; + for (int i = 0; i < 10; i++) + if (clients[i] && strcmp(clients[i]->room, cli->room) == 0) + count++; + + char header[BUFFER_SIZE]; + snprintf(header, sizeof(header), "[you are in '%s' among %d]\n\n", cli->room, count); + send_to_client(cli->socket, header); + + for (int i = 0; i < 10; i++) { + if (clients[i] && strcmp(clients[i]->room, cli->room) == 0) { + char line[BUFFER_SIZE]; + snprintf(line, sizeof(line), "%s@%s\n", clients[i]->username, + inet_ntoa(clients[i]->address.sin_addr)); + send_to_client(cli->socket, line); + } + } + pthread_mutex_unlock(&clients_mutex); + } + else { + broadcast_message(buffer, cli->socket); + } + } + + close(cli->socket); + pthread_mutex_lock(&clients_mutex); + for (int i = 0; i < 10; i++) { + if (clients[i] == cli) { + leave_chatroom(cli); + clients[i] = NULL; + break; + } + } + pthread_mutex_unlock(&clients_mutex); + free(cli); + pthread_exit(NULL); +} |