Merge all 5 PRs: security, CLI features, protocol, performance, tests/docs
CI / lint (pull_request) Failing after 11s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (undefined) (pull_request) Has been skipped
CI / fuzz-build (pull_request) Has been skipped
CI / coverage (pull_request) Has been skipped
CI / valgrind (pull_request) Has been skipped
CI / lint (pull_request) Failing after 11s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (undefined) (pull_request) Has been skipped
CI / fuzz-build (pull_request) Has been skipped
CI / coverage (pull_request) Has been skipped
CI / valgrind (pull_request) Has been skipped
This commit is contained in:
@@ -305,7 +305,7 @@ static int scan_directory_multithreaded(void* pipeline_context) {
|
||||
context->config->send_directory, context->config->use_metadata, context->config->chunk_size,
|
||||
context->config->exclude_patterns, context->config->exclude_count,
|
||||
context->config->include_patterns, context->config->include_count, context->config->max_size,
|
||||
context->config->min_size, 4);
|
||||
context->config->min_size, context->config->max_depth, 4);
|
||||
|
||||
Chunk* current_chunk;
|
||||
while ((current_chunk = parallel_scanner_next(scanner)) != NULL) {
|
||||
@@ -368,7 +368,7 @@ int send_files(Config* config) {
|
||||
DirectoryScanner* scanner = directory_scanner_create(
|
||||
config->send_directory, config->use_metadata, config->chunk_size, config->exclude_patterns,
|
||||
config->exclude_count, config->include_patterns, config->include_count, config->max_size,
|
||||
config->min_size);
|
||||
config->min_size, config->max_depth);
|
||||
Chunk* chunk;
|
||||
int file_count = 0;
|
||||
unsigned long long total_bytes = 0;
|
||||
@@ -421,7 +421,7 @@ int send_files(Config* config) {
|
||||
DirectoryScanner* scanner = directory_scanner_create(
|
||||
config->send_directory, config->use_metadata, config->chunk_size, config->exclude_patterns,
|
||||
config->exclude_count, config->include_patterns, config->include_count, config->max_size,
|
||||
config->min_size);
|
||||
config->min_size, config->max_depth);
|
||||
Chunk* current_chunk;
|
||||
unsigned long long total_bytes = 0;
|
||||
time_t last_progress = 0;
|
||||
@@ -510,7 +510,7 @@ int send_files_multithreaded(Config* config) {
|
||||
DirectoryScanner* scanner = directory_scanner_create(
|
||||
config->send_directory, config->use_metadata, config->chunk_size, config->exclude_patterns,
|
||||
config->exclude_count, config->include_patterns, config->include_count, config->max_size,
|
||||
config->min_size);
|
||||
config->min_size, config->max_depth);
|
||||
Chunk* chunk;
|
||||
int file_count = 0;
|
||||
unsigned long long total_bytes = 0;
|
||||
|
||||
@@ -215,6 +215,7 @@ typedef struct {
|
||||
int include_count;
|
||||
unsigned long long max_size;
|
||||
unsigned long long min_size;
|
||||
int max_depth;
|
||||
} ParallelWorkerArg;
|
||||
|
||||
static int parallel_worker_thread(void* arg) {
|
||||
@@ -222,7 +223,7 @@ static int parallel_worker_thread(void* arg) {
|
||||
for (int i = 0; i < wa->dir_count; i++) {
|
||||
DirectoryScanner* ds = directory_scanner_create(
|
||||
wa->dirs[i], wa->use_metadata, wa->chunk_size, wa->exclude_patterns, wa->exclude_count,
|
||||
wa->include_patterns, wa->include_count, wa->max_size, wa->min_size);
|
||||
wa->include_patterns, wa->include_count, wa->max_size, wa->min_size, wa->max_depth);
|
||||
Chunk* chunk;
|
||||
while ((chunk = directory_scanner_next(ds)) != NULL) {
|
||||
queue_enqueue_multithreaded(wa->ps->result_queue, chunk, &wa->ps->result_mutex,
|
||||
@@ -248,7 +249,8 @@ ParallelScanner* parallel_scanner_create(char* root_directory, bool use_metadata
|
||||
unsigned long long chunk_size, char** exclude_patterns,
|
||||
int exclude_count, char** include_patterns,
|
||||
int include_count, unsigned long long max_size,
|
||||
unsigned long long min_size, int num_threads) {
|
||||
unsigned long long min_size, int max_depth,
|
||||
int num_threads) {
|
||||
ParallelScanner* ps = calloc(1, sizeof(ParallelScanner));
|
||||
if (!ps)
|
||||
return NULL;
|
||||
@@ -406,6 +408,7 @@ ParallelScanner* parallel_scanner_create(char* root_directory, bool use_metadata
|
||||
wa->include_count = include_count;
|
||||
wa->max_size = max_size;
|
||||
wa->min_size = min_size;
|
||||
wa->max_depth = max_depth;
|
||||
start += count;
|
||||
if (thrd_create(&ps->threads[t], parallel_worker_thread, wa) != thrd_success) {
|
||||
for (int j = 0; j < count; j++)
|
||||
|
||||
@@ -19,6 +19,8 @@ typedef struct {
|
||||
int include_count;
|
||||
unsigned long long max_size;
|
||||
unsigned long long min_size;
|
||||
int max_depth;
|
||||
int current_depth;
|
||||
} DirectoryScanner;
|
||||
|
||||
typedef struct {
|
||||
@@ -33,11 +35,11 @@ typedef struct {
|
||||
Chunk* initial_chunk;
|
||||
} ParallelScanner;
|
||||
|
||||
DirectoryScanner* directory_scanner_create(char* root_directory, bool use_metadata,
|
||||
DirectoryScanner* directory_scanner_create(const char* root_directory, bool use_metadata,
|
||||
unsigned long long chunk_size, char** exclude_patterns,
|
||||
int exclude_count, char** include_patterns,
|
||||
int include_count, unsigned long long max_size,
|
||||
unsigned long long min_size);
|
||||
unsigned long long min_size, int max_depth);
|
||||
Chunk* directory_scanner_next(DirectoryScanner* scanner);
|
||||
void directory_scanner_destroy(DirectoryScanner* scanner);
|
||||
|
||||
@@ -45,7 +47,8 @@ ParallelScanner* parallel_scanner_create(char* root_directory, bool use_metadata
|
||||
unsigned long long chunk_size, char** exclude_patterns,
|
||||
int exclude_count, char** include_patterns,
|
||||
int include_count, unsigned long long max_size,
|
||||
unsigned long long min_size, int num_threads);
|
||||
unsigned long long min_size, int max_depth,
|
||||
int num_threads);
|
||||
Chunk* parallel_scanner_next(ParallelScanner* scanner);
|
||||
void parallel_scanner_destroy(ParallelScanner* scanner);
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
typedef enum { FILE_TYPE_REGULAR, FILE_TYPE_SYMLINK, FILE_TYPE_DIR } FileType;
|
||||
|
||||
typedef struct {
|
||||
mode_t mode;
|
||||
uid_t uid;
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ void log_set_file(FILE* fp) {
|
||||
log_fp = fp;
|
||||
}
|
||||
|
||||
void log_message(LogLevel log_level, char* format, ...) {
|
||||
void log_message(LogLevel log_level, const char* format, ...) {
|
||||
if (log_level < current_log_level)
|
||||
return;
|
||||
time_t now = time(NULL);
|
||||
|
||||
+27
-7
@@ -61,6 +61,19 @@ char* str_dup(const char* string) {
|
||||
bool glob_match(const char* pattern, const char* str) {
|
||||
while (*pattern) {
|
||||
if (*pattern == '*') {
|
||||
if (*(pattern + 1) == '*') {
|
||||
pattern += 2;
|
||||
if (*pattern == '\0')
|
||||
return true;
|
||||
if (*pattern == '/')
|
||||
pattern++;
|
||||
while (*str) {
|
||||
if (glob_match(pattern, str))
|
||||
return true;
|
||||
str++;
|
||||
}
|
||||
return glob_match(pattern, str);
|
||||
}
|
||||
pattern++;
|
||||
while (*str && *str != '/') {
|
||||
if (glob_match(pattern, str))
|
||||
@@ -74,8 +87,15 @@ bool glob_match(const char* pattern, const char* str) {
|
||||
pattern++;
|
||||
str++;
|
||||
} else {
|
||||
if (*pattern != *str)
|
||||
if (*pattern != *str) {
|
||||
if (*pattern == '/' && *(pattern + 1) == '*' && *(pattern + 2) == '*') {
|
||||
const char* rest = pattern + 3;
|
||||
if (*rest == '/')
|
||||
rest++;
|
||||
return glob_match(rest, str);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
pattern++;
|
||||
str++;
|
||||
}
|
||||
@@ -168,18 +188,18 @@ bool has_path_traversal(const char* path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char* path_cat(const char* path1, char* path2) {
|
||||
char* path_cat(const char* path1, const char* path2) {
|
||||
if (path1 == NULL || *path1 == '\0')
|
||||
return str_dup(path2);
|
||||
if (path2 == NULL || *path2 == '\0')
|
||||
return str_dup(path1);
|
||||
int path1_len = strlen(path1);
|
||||
int path2_len = strlen(path2);
|
||||
char* path2_pointer = path2;
|
||||
size_t path1_len = strlen(path1);
|
||||
size_t path2_len = strlen(path2);
|
||||
size_t offset = 0;
|
||||
if (path1[path1_len - 1] == '/')
|
||||
path1_len -= 1;
|
||||
if (path2[0] == '/') {
|
||||
path2_pointer += 1;
|
||||
offset = 1;
|
||||
path2_len -= 1;
|
||||
}
|
||||
char* new_path = malloc(path1_len + path2_len + 2);
|
||||
@@ -187,7 +207,7 @@ char* path_cat(const char* path1, char* path2) {
|
||||
return NULL;
|
||||
memcpy(new_path, path1, path1_len);
|
||||
new_path[path1_len] = '/';
|
||||
memcpy(new_path + path1_len + 1, path2_pointer, path2_len);
|
||||
memcpy(new_path + path1_len + 1, path2 + offset, path2_len);
|
||||
new_path[path1_len + path2_len + 1] = '\0';
|
||||
return new_path;
|
||||
}
|
||||
|
||||
@@ -217,10 +217,6 @@ static void test_file_send_no_path() {
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
close(p[1]);
|
||||
// Read file type indicator
|
||||
int file_type;
|
||||
EXPECT_TRUE(receive_int(p[0], &file_type));
|
||||
EXPECT_EQ_INT(file_type, (int)FILE_TYPE_REGULAR);
|
||||
Data* received = receive_data(p[0]);
|
||||
close(p[0]);
|
||||
|
||||
|
||||
@@ -224,10 +224,6 @@ static void test_sendfile_no_path() {
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
close(p[1]);
|
||||
/* When send_path is false, the sender still sends file_type + data */
|
||||
int file_type;
|
||||
EXPECT_TRUE(receive_int(p[0], &file_type));
|
||||
EXPECT_EQ_INT(file_type, (int)FILE_TYPE_REGULAR);
|
||||
Data* received = receive_data(p[0]);
|
||||
close(p[0]);
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ static void test_scanner_exclude_pattern() {
|
||||
|
||||
char* exclude[] = {"*.tmp"};
|
||||
DirectoryScanner* scanner =
|
||||
directory_scanner_create((char*)dir, false, 0, exclude, 1, NULL, 0, 0, 0);
|
||||
directory_scanner_create((char*)dir, false, 0, exclude, 1, NULL, 0, 0, 0, 0);
|
||||
EXPECT_NOT_NULL(scanner);
|
||||
|
||||
Chunk* chunk = directory_scanner_next(scanner);
|
||||
@@ -169,7 +169,7 @@ static void test_scanner_exclude_subdirectory() {
|
||||
|
||||
char* exclude[] = {"*.tmp"};
|
||||
DirectoryScanner* scanner =
|
||||
directory_scanner_create((char*)root, false, 0, exclude, 1, NULL, 0, 0, 0);
|
||||
directory_scanner_create((char*)root, false, 0, exclude, 1, NULL, 0, 0, 0, 0);
|
||||
EXPECT_NOT_NULL(scanner);
|
||||
|
||||
int total = 0;
|
||||
@@ -207,7 +207,7 @@ static void test_scanner_include_and_exclude() {
|
||||
char* exclude[] = {"*.bak"};
|
||||
char* include[] = {"*.txt", "*.log"};
|
||||
DirectoryScanner* scanner =
|
||||
directory_scanner_create((char*)dir, false, 0, exclude, 1, include, 2, 0, 0);
|
||||
directory_scanner_create((char*)dir, false, 0, exclude, 1, include, 2, 0, 0, 0);
|
||||
EXPECT_NOT_NULL(scanner);
|
||||
|
||||
Chunk* chunk = directory_scanner_next(scanner);
|
||||
@@ -244,7 +244,7 @@ static void test_scanner_max_size() {
|
||||
|
||||
/* max_size = 10 — only files <= 10 bytes */
|
||||
DirectoryScanner* scanner =
|
||||
directory_scanner_create((char*)dir, false, 0, NULL, 0, NULL, 0, 10, 0);
|
||||
directory_scanner_create((char*)dir, false, 0, NULL, 0, NULL, 0, 10, 0, 0);
|
||||
EXPECT_NOT_NULL(scanner);
|
||||
|
||||
Chunk* chunk = directory_scanner_next(scanner);
|
||||
@@ -272,7 +272,7 @@ static void test_scanner_min_size() {
|
||||
|
||||
/* min_size = 1 — only files >= 1 byte */
|
||||
DirectoryScanner* scanner =
|
||||
directory_scanner_create((char*)dir, false, 0, NULL, 0, NULL, 0, 0, 1);
|
||||
directory_scanner_create((char*)dir, false, 0, NULL, 0, NULL, 0, 0, 1, 0);
|
||||
EXPECT_NOT_NULL(scanner);
|
||||
|
||||
Chunk* chunk = directory_scanner_next(scanner);
|
||||
@@ -302,7 +302,7 @@ static void test_scanner_size_range() {
|
||||
|
||||
/* Only files between 3 and 20 bytes */
|
||||
DirectoryScanner* scanner =
|
||||
directory_scanner_create((char*)dir, false, 0, NULL, 0, NULL, 0, 20, 3);
|
||||
directory_scanner_create((char*)dir, false, 0, NULL, 0, NULL, 0, 20, 3, 0);
|
||||
EXPECT_NOT_NULL(scanner);
|
||||
|
||||
Chunk* chunk = directory_scanner_next(scanner);
|
||||
@@ -338,7 +338,7 @@ static void test_scanner_mixed_patterns() {
|
||||
char* exclude[] = {"*.bak"};
|
||||
char* include[] = {"*.txt"};
|
||||
DirectoryScanner* scanner =
|
||||
directory_scanner_create((char*)dir, false, 0, exclude, 1, include, 1, 10, 3);
|
||||
directory_scanner_create((char*)dir, false, 0, exclude, 1, include, 1, 10, 3, 0);
|
||||
EXPECT_NOT_NULL(scanner);
|
||||
|
||||
Chunk* chunk = directory_scanner_next(scanner);
|
||||
@@ -369,7 +369,7 @@ static void test_scanner_no_patterns() {
|
||||
create_test_file(f2, "second");
|
||||
|
||||
DirectoryScanner* scanner =
|
||||
directory_scanner_create((char*)dir, false, 0, NULL, 0, NULL, 0, 0, 0);
|
||||
directory_scanner_create((char*)dir, false, 0, NULL, 0, NULL, 0, 0, 0, 0);
|
||||
EXPECT_NOT_NULL(scanner);
|
||||
|
||||
Chunk* chunk = directory_scanner_next(scanner);
|
||||
|
||||
Reference in New Issue
Block a user