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 456a95e..0000000 Binary files a/build/bin/pupes-backup-server and /dev/null differ diff --git a/build/obj/main.o b/build/obj/main.o deleted file mode 100644 index 9780156..0000000 Binary files a/build/obj/main.o and /dev/null differ 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);