// // Created by Ajurna on 30/07/2025. // #include "server05.h" #include #include #include #include "data.h" #include #include #include #define PCRE2_CODE_UNIT_WIDTH 8 #include const char *newline = "\n"; const char *bogus_address = "7YWHMfk9JZe0LM0g1ZauHuiSxhI"; int main() { SOCKET server = get_listen_socket(); SOCKADDR_IN clientAddr; SOCKET client; int clientAddrSize = sizeof(clientAddr); int connection_number = 1; char *message = "Please pay the ticket price of 15 Boguscoins to one of these addresses: 7ABnYzozPt2cyDHQqDq2ExIMz53xXVcErn 7z6kM0VlNJpZiqTEHmRjxW9FbVCkv2flb 7qReHdk11Ai67nRvvfTQXFjPZH3X"; char *new_message = replace_bogus_coin(message); // replace_bogus_coin(message); printf("%s\n", new_message); // exit(0); printf("Listening for incoming connections...\n"); while((client = accept(server, (SOCKADDR *)&clientAddr, &clientAddrSize)) != INVALID_SOCKET) { handle_args_t *args = malloc(sizeof(handle_args_t)); args->client = client; args->server = get_chat_socket(); args->connection = connection_number++; pthread_t thread; pthread_create(&thread, nullptr, handle_server, args); pthread_create(&thread, nullptr, handle_client, args); } return 0; } void *handle_server(void *args) { handle_args_t *handleArgs = args; char buffer[1024] = {}; int bytesReceived; printf("{%d} Server connected\n", handleArgs->connection); char_array_t *data = char_array_create(1024); while ((bytesReceived = recv(handleArgs->server, buffer, sizeof(buffer), 0)) > 0) { printf("server sent {%d}: |%d| \n", handleArgs->connection, bytesReceived); char_array_append(data, buffer, bytesReceived); char *request; while ((request = char_array_get_until_char(data, '\n')) != NULL) { printf("{%d} server Said: %s\n", handleArgs->connection, request); request = replace_bogus_coin(request); send(handleArgs->client, request, strlen(request), 0); send(handleArgs->client, newline, strlen(newline), 0); free(request); } memset(buffer, 0, sizeof(buffer)); } // closesocket(handleArgs->server); return nullptr; } char *replace_bogus_coin(char *message) { pcre2_code *re; PCRE2_SPTR pattern = (PCRE2_SPTR)"\\b7\\w{25,34}\\b"; PCRE2_SPTR subject = (PCRE2_SPTR)message; size_t subject_length = strlen((char *)subject); int errornumber; PCRE2_SIZE erroroffset; PCRE2_SIZE *ovector; int rc; size_t offset = 0; // Keep track of where we are in the string // Compile the pattern re = pcre2_compile( pattern, PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset, NULL); if (re == NULL) { PCRE2_UCHAR buff[256]; pcre2_get_error_message(errornumber, buff, sizeof(buff)); printf("PCRE2 compilation failed at offset %d: %s\n", (int)erroroffset, buff); return message; } // Create match data block pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(re, NULL); char *result = strdup(message); // Create a copy of the original message // Loop until no more matches are found while (offset < subject_length) { rc = pcre2_match( re, subject, subject_length, offset, // Start from last match position 0, match_data, NULL); if (rc < 0) { break; // No more matches } ovector = pcre2_get_ovector_pointer(match_data); PCRE2_SIZE start = ovector[0]; PCRE2_SIZE end = ovector[1]; // Replace the matched text with bogus_address char *temp = calloc(strlen(result) + strlen(bogus_address) + 1, sizeof(char)); strncpy(temp, result, start); strcat(temp, bogus_address); strcat(temp, result + end); free(result); result = temp; // Update the subject and length for next iteration subject = (PCRE2_SPTR)result; subject_length = strlen(result); offset = start + strlen(bogus_address); } // Clean up pcre2_match_data_free(match_data); pcre2_code_free(re); return result; } void *handle_client(void *args) { handle_args_t *handleArgs = args; char buffer[1024] = {}; int bytesReceived; printf("{%d} Client connected\n", handleArgs->connection); char_array_t *data = char_array_create(1024); while ((bytesReceived = recv(handleArgs->client, buffer, sizeof(buffer), 0)) > 0) { printf("server sent {%d}: |%d| \n", handleArgs->connection, bytesReceived); char_array_append(data, buffer, bytesReceived); char *request; while ((request = char_array_get_until_char(data, '\n')) != NULL) { printf("{%d} client Said: %s\n", handleArgs->connection, request); request = replace_bogus_coin(request); send(handleArgs->server, request, strlen(request), 0); send(handleArgs->server, newline, strlen(newline), 0); free(request); } memset(buffer, 0, sizeof(buffer)); } // closesocket(handleArgs->client); return nullptr; } SOCKET get_chat_socket() { WSADATA WSAData; SOCKADDR_IN serverAddr; struct hostent * host = gethostbyname("chat.protohackers.com"); WSAStartup(MAKEWORD(2,0), &WSAData); SOCKET server = socket(AF_INET, SOCK_STREAM, 0 ); serverAddr.sin_addr.s_addr = AF_INET; serverAddr.sin_family = AF_INET; memcpy(&serverAddr.sin_addr.s_addr, host->h_addr_list[0], host->h_length); serverAddr.sin_port = htons(16963); connect(server, (SOCKADDR *) & serverAddr, sizeof (serverAddr)); return server; }