diff --git a/include/chat_room.h b/include/chat_room.h index 0b50d5f..ac913fa 100644 --- a/include/chat_room.h +++ b/include/chat_room.h @@ -36,9 +36,6 @@ void room_remove_client(chat_room_t *room, struct client *client); /* Broadcast message to all clients */ void room_broadcast(chat_room_t *room, const message_t *msg); -/* Add message to room history */ -void room_add_message(chat_room_t *room, const message_t *msg); - /* Get message by index (thread-safe value copy) */ bool room_get_message(chat_room_t *room, int index, message_t *out); diff --git a/include/ssh_server.h b/include/ssh_server.h index bf77b9e..fcabfcd 100644 --- a/include/ssh_server.h +++ b/include/ssh_server.h @@ -13,8 +13,8 @@ typedef struct client { ssh_channel channel; /* SSH channel */ char username[MAX_USERNAME_LEN]; char client_ip[INET6_ADDRSTRLEN]; - int width; - int height; + _Atomic int width; + _Atomic int height; client_mode_t mode; help_lang_t help_lang; int scroll_pos; diff --git a/src/chat_room.c b/src/chat_room.c index 0cd10f4..ebaea79 100644 --- a/src/chat_room.c +++ b/src/chat_room.c @@ -87,23 +87,9 @@ void room_remove_client(chat_room_t *room, struct client *client) { pthread_rwlock_unlock(&room->lock); } -/* Broadcast message to all clients */ -void room_broadcast(chat_room_t *room, const message_t *msg) { - pthread_rwlock_wrlock(&room->lock); - - /* Add to history */ - room_add_message(room, msg); - room->update_seq++; - - pthread_rwlock_unlock(&room->lock); -} - -/* Add message to room history */ -void room_add_message(chat_room_t *room, const message_t *msg) { - /* Caller should hold write lock */ - +/* Add message to room history (caller must hold write lock) */ +static void room_add_message(chat_room_t *room, const message_t *msg) { if (room->message_count >= MAX_MESSAGES) { - /* Shift messages to make room */ memmove(&room->messages[0], &room->messages[1], (MAX_MESSAGES - 1) * sizeof(message_t)); room->message_count = MAX_MESSAGES - 1; @@ -112,6 +98,16 @@ void room_add_message(chat_room_t *room, const message_t *msg) { room->messages[room->message_count++] = *msg; } +/* Broadcast message to all clients */ +void room_broadcast(chat_room_t *room, const message_t *msg) { + pthread_rwlock_wrlock(&room->lock); + + room_add_message(room, msg); + room->update_seq++; + + pthread_rwlock_unlock(&room->lock); +} + /* Get message by index (thread-safe value copy) */ bool room_get_message(chat_room_t *room, int index, message_t *out) { if (!room || !out) return false; diff --git a/src/message.c b/src/message.c index e2ba166..068b03d 100644 --- a/src/message.c +++ b/src/message.c @@ -61,7 +61,7 @@ int message_load(message_t **messages, int max_messages) { } long file_size = ftell(fp); - if (file_size == 0) { + if (file_size <= 0) { fclose(fp); *messages = msg_array; return 0; diff --git a/src/ssh_server.c b/src/ssh_server.c index 9f8b3d2..60969eb 100644 --- a/src/ssh_server.c +++ b/src/ssh_server.c @@ -1069,7 +1069,10 @@ static int execute_exec_command(client_t *client) { /* Execute a command */ static void execute_command(client_t *client) { - char *cmd = client->command_input; + char cmd_buf[256]; + strncpy(cmd_buf, client->command_input, sizeof(cmd_buf) - 1); + cmd_buf[sizeof(cmd_buf) - 1] = '\0'; + char *cmd = cmd_buf; char output[2048] = {0}; size_t pos = 0; @@ -1118,8 +1121,14 @@ static void execute_command(client_t *client) { "list, users, who - Show online users\n" "help, commands - Show this help\n" "clear, cls - Clear command output\n" + "q, quit, exit - Disconnect from chat\n" "========================================\n"); + } else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0 || + strcmp(cmd, "exit") == 0) { + client->connected = false; + return; + } else if (strcmp(cmd, "clear") == 0 || strcmp(cmd, "cls") == 0) { buffer_appendf(output, sizeof(output), &pos, "Command output cleared\n"); @@ -1367,6 +1376,7 @@ void* client_handle_session(void *arg) { join_msg.username[MAX_USERNAME_LEN - 1] = '\0'; snprintf(join_msg.content, MAX_MESSAGE_LEN, "%s 加入了聊天室", client->username); room_broadcast(g_room, &join_msg); + message_save(&join_msg); /* Render initial screen */ tui_render_screen(client); @@ -1496,6 +1506,7 @@ cleanup: client->connected = false; room_remove_client(g_room, client); room_broadcast(g_room, &leave_msg); + message_save(&leave_msg); } release_ip_connection(client->client_ip); @@ -1768,9 +1779,11 @@ static int client_channel_window_change(ssh_session session, ssh_channel channel return SSH_ERROR; } - client->width = width; - client->height = height; - sanitize_terminal_size(&client->width, &client->height); + int w = width; + int h = height; + sanitize_terminal_size(&w, &h); + client->width = w; + client->height = h; client->redraw_pending = true; return SSH_OK; } @@ -1942,9 +1955,11 @@ static void *bootstrap_client_session(void *arg) { client->session = session; client->channel = channel; - client->width = ctx->pty_width; - client->height = ctx->pty_height; - sanitize_terminal_size(&client->width, &client->height); + int init_w = ctx->pty_width; + int init_h = ctx->pty_height; + sanitize_terminal_size(&init_w, &init_h); + client->width = init_w; + client->height = init_h; client->ref_count = 1; pthread_mutex_init(&client->ref_lock, NULL); pthread_mutex_init(&client->io_lock, NULL); diff --git a/src/tui.c b/src/tui.c index 2eb4cdf..8063369 100644 --- a/src/tui.c +++ b/src/tui.c @@ -386,7 +386,7 @@ void tui_render_help(client_t *client) { /* Help content */ const char *help_text = tui_get_help_text(client->help_lang); - char help_copy[4096]; + char help_copy[8192]; strncpy(help_copy, help_text, sizeof(help_copy) - 1); help_copy[sizeof(help_copy) - 1] = '\0'; diff --git a/tests/unit/Makefile b/tests/unit/Makefile index 0fe36d8..bc1496c 100644 --- a/tests/unit/Makefile +++ b/tests/unit/Makefile @@ -6,6 +6,7 @@ LDFLAGS = -pthread # Source files UTF8_SRC = ../../src/utf8.c MESSAGE_SRC = ../../src/message.c +COMMON_SRC = ../../src/common.c TESTS = test_utf8 test_message @@ -16,7 +17,7 @@ all: $(TESTS) test_utf8: test_utf8.c $(UTF8_SRC) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -test_message: test_message.c $(MESSAGE_SRC) $(UTF8_SRC) +test_message: test_message.c $(MESSAGE_SRC) $(UTF8_SRC) $(COMMON_SRC) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) run: all