From 81e60ce1cc6f977efc8c894ab49e2beb258936ea Mon Sep 17 00:00:00 2001 From: PoliEcho Date: Sat, 11 Oct 2025 21:59:09 +0200 Subject: [PATCH] add multithreading --- .gitignore | 3 +- Makefile | 2 ++ build/bin/pupes-backup-server | Bin 14624 -> 0 bytes build/obj/main.o | Bin 7480 -> 0 bytes pupes-backup.service | 12 +++++++ src/main.c | 63 ++++++++++++++++++++++++---------- 6 files changed, 61 insertions(+), 19 deletions(-) delete mode 100755 build/bin/pupes-backup-server delete mode 100644 build/obj/main.o create mode 100644 pupes-backup.service diff --git a/.gitignore b/.gitignore index 52aaf84..78fc2ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ test compile_commands.json .vscode -.cache \ No newline at end of file +.cache +build \ No newline at end of file diff --git a/Makefile b/Makefile index 4aa6f34..b01e750 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,8 @@ $(OBJ_PATH)/%.o: $(SRC_PATH)/%.c install: @install -vpm 755 -o root -g root $(BIN_PATH)/$(BIN_NAME) /usr/bin/ + @install -vpm 644 -o root -g root pupes-backup.service /etc/systemd/system/ + useradd -m -d /srv/backup -r -s /usr/sbin/nologin pupes_backup clean: rm -fr build diff --git a/build/bin/pupes-backup-server b/build/bin/pupes-backup-server deleted file mode 100755 index 456a95ed73bb6b82464f50756f26c4208d256a10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14624 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 C7OZyw diff --git a/build/obj/main.o b/build/obj/main.o deleted file mode 100644 index 97801563e9ba3d6562a30daa8a59e60405bfa772..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7480 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 C?q)Io diff --git a/pupes-backup.service b/pupes-backup.service new file mode 100644 index 0000000..ea1bba1 --- /dev/null +++ b/pupes-backup.service @@ -0,0 +1,12 @@ +[Unit] +Description=ssh port forwarding service +After=network.target +StartLimitIntervalSec=0 + +[Service] +User=pupes_backup +WorkingDirectory=/srv/backup +ExecStart=/usr/bin/pupes-backup-server /srv/backup 192.168.1.213 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/src/main.c b/src/main.c index 7673c3b..a6de656 100644 --- a/src/main.c +++ b/src/main.c @@ -14,20 +14,36 @@ #include #include #include "color.h" +#include -#define ALLOWED_IP "192.168.1.213" #define MAX_FILE_SIZE_G 100 #define MAX_FILE_SIZE (size_t)MAX_FILE_SIZE_G*1073741824 -#define READ_BUFFER_SIZE 32768 // 256K +#define READ_BUFFER_SIZE 134217728 // 256M const char* filename_base = "backup"; +struct thread_context { + int fd; + char* buff; + size_t count; +}; +_Bool write_thread_done = 1; int sockfd; +void* thread_function(void* arg) { + struct thread_context* context = arg; + if (write(context->fd, context->buff,context->count) == -1) { + fprintf(stderr, YELLOW"["RED"CRITICAL"YELLOW"]"RESET" Error: %s, when writing failed file may be corupted\n", strerror(errno)); + } + write_thread_done = 1; + free(context->buff); + free(context); + return NULL; +} int main(int argc, char* argv[]) { - if (argc < 2) { - fprintf(stderr, "Usage:\n%s [BACKUP DIRECTORY]\n", argv[0]); + if (argc < 3) { + fprintf(stderr, "Usage:\n%s [BACKUP DIRECTORY] [ALLOWED IP]\n", argv[0]); return EINVAL; } int client_fd; @@ -78,7 +94,7 @@ int main(int argc, char* argv[]) { inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip, INET_ADDRSTRLEN); - if (strcmp(client_ip, ALLOWED_IP) == 0) { + if (strcmp(client_ip, argv[2]) == 0) { printf("Accepted connection from %s\n", client_ip); const time_t unix_time = time(NULL); @@ -99,30 +115,41 @@ int main(int argc, char* argv[]) { ssize_t bytes_transferred; size_t receved_this_read_cicle = SIZE_MAX; size_t total_received = 0; - char* read_buffer = malloc(READ_BUFFER_SIZE); + pthread_t write_thread; + while (receved_this_read_cicle != 0 && total_received < MAX_FILE_SIZE){ + char* read_buffer = malloc(READ_BUFFER_SIZE); receved_this_read_cicle = 0; - while ((bytes_transferred = read(client_fd, read_buffer, READ_BUFFER_SIZE - receved_this_read_cicle)) > 0) { - if (bytes_transferred == -1) { - fprintf(stderr, YELLOW"["RED"CRITICAL"YELLOW"]"RESET" Error: %s, when receving file: %s failed file may be corupted\n", strerror(errno) ,full_filename_path); - goto client_cleanup; - } - receved_this_read_cicle += bytes_transferred; + while ((bytes_transferred = read(client_fd, read_buffer+receved_this_read_cicle, READ_BUFFER_SIZE - receved_this_read_cicle)) > 0) { + if (bytes_transferred == -1) { + fprintf(stderr, YELLOW"["RED"CRITICAL"YELLOW"]"RESET" Error: %s, when receving file: %s failed file may be corupted\n", strerror(errno) ,full_filename_path); + goto client_cleanup; + } + receved_this_read_cicle += bytes_transferred; } if (receved_this_read_cicle == 0) {break;} total_received += receved_this_read_cicle; - if (write(savefile_fd, read_buffer, receved_this_read_cicle) == -1) { - fprintf(stderr, YELLOW"["RED"CRITICAL"YELLOW"]"RESET" Error: %s, when writing file: %s failed file may be corupted\n", strerror(errno) ,full_filename_path); - }} - client_cleanup: + if (!write_thread_done) {pthread_join(write_thread, NULL);} + { + struct thread_context* thread_context = malloc(sizeof(struct thread_context)); + thread_context->buff = read_buffer; + thread_context->count = receved_this_read_cicle; + thread_context->fd = savefile_fd; + write_thread_done = 0; + if (pthread_create(&write_thread, NULL, thread_function, thread_context) != 0) { + perror("Failed to create write thread"); + return 1; + }} +} + client_cleanup: + if (!write_thread_done) {pthread_join(write_thread, NULL);}; printf("finished handling: %s\n",full_filename_path); - free(read_buffer); free(full_filename_path); - close(savefile_fd); close(client_fd); + close(savefile_fd); } else { printf("Rejected connection from %s\n", client_ip); close(client_fd);