add multithreading

This commit is contained in:
PoliEcho 2025-10-11 21:59:09 +02:00
parent 724b0bb5f6
commit 81e60ce1cc
6 changed files with 61 additions and 19 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
test test
compile_commands.json compile_commands.json
.vscode .vscode
.cache .cache
build

View File

@ -42,6 +42,8 @@ $(OBJ_PATH)/%.o: $(SRC_PATH)/%.c
install: install:
@install -vpm 755 -o root -g root $(BIN_PATH)/$(BIN_NAME) /usr/bin/ @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: clean:
rm -fr build rm -fr build

Binary file not shown.

Binary file not shown.

12
pupes-backup.service Normal file
View File

@ -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

View File

@ -14,20 +14,36 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/sendfile.h> #include <sys/sendfile.h>
#include "color.h" #include "color.h"
#include <pthread.h>
#define ALLOWED_IP "192.168.1.213"
#define MAX_FILE_SIZE_G 100 #define MAX_FILE_SIZE_G 100
#define MAX_FILE_SIZE (size_t)MAX_FILE_SIZE_G*1073741824 #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"; const char* filename_base = "backup";
struct thread_context {
int fd;
char* buff;
size_t count;
};
_Bool write_thread_done = 1;
int sockfd; 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[]) { int main(int argc, char* argv[]) {
if (argc < 2) { if (argc < 3) {
fprintf(stderr, "Usage:\n%s [BACKUP DIRECTORY]\n", argv[0]); fprintf(stderr, "Usage:\n%s [BACKUP DIRECTORY] [ALLOWED IP]\n", argv[0]);
return EINVAL; return EINVAL;
} }
int client_fd; 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); 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); printf("Accepted connection from %s\n", client_ip);
const time_t unix_time = time(NULL); const time_t unix_time = time(NULL);
@ -99,30 +115,41 @@ int main(int argc, char* argv[]) {
ssize_t bytes_transferred; ssize_t bytes_transferred;
size_t receved_this_read_cicle = SIZE_MAX; size_t receved_this_read_cicle = SIZE_MAX;
size_t total_received = 0; 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){ while (receved_this_read_cicle != 0 && total_received < MAX_FILE_SIZE){
char* read_buffer = malloc(READ_BUFFER_SIZE);
receved_this_read_cicle = 0; receved_this_read_cicle = 0;
while ((bytes_transferred = read(client_fd, read_buffer, READ_BUFFER_SIZE - receved_this_read_cicle)) > 0) { while ((bytes_transferred = read(client_fd, read_buffer+receved_this_read_cicle, READ_BUFFER_SIZE - receved_this_read_cicle)) > 0) {
if (bytes_transferred == -1) { 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); 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; goto client_cleanup;
} }
receved_this_read_cicle += bytes_transferred; receved_this_read_cicle += bytes_transferred;
} }
if (receved_this_read_cicle == 0) {break;} if (receved_this_read_cicle == 0) {break;}
total_received += receved_this_read_cicle; total_received += receved_this_read_cicle;
if (write(savefile_fd, read_buffer, receved_this_read_cicle) == -1) { if (!write_thread_done) {pthread_join(write_thread, NULL);}
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:
{
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); printf("finished handling: %s\n",full_filename_path);
free(read_buffer);
free(full_filename_path); free(full_filename_path);
close(savefile_fd);
close(client_fd); close(client_fd);
close(savefile_fd);
} else { } else {
printf("Rejected connection from %s\n", client_ip); printf("Rejected connection from %s\n", client_ip);
close(client_fd); close(client_fd);