Merge remaining 4 PRs: memory safety, refactoring, test coverage, integration cleanup #93
@@ -70,10 +70,14 @@ int main(int argc, char* argv[]) {
|
|||||||
save_to_disk = true;
|
save_to_disk = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Config* config = config_create(str_dup(PROTOCOL_VERSION), NULL, NULL, save_to_disk, false, false,
|
|
||||||
false, false, 5, false, 0);
|
|
||||||
int exit_code = 0;
|
int exit_code = 0;
|
||||||
bool config_owned_by_pipeline = false;
|
bool config_owned_by_pipeline = false;
|
||||||
|
Config* config = config_create(str_dup(PROTOCOL_VERSION), NULL, NULL, save_to_disk, false, false,
|
||||||
|
false, false, 5, false, 0);
|
||||||
|
if (config == NULL) {
|
||||||
|
exit_code = 1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
int positional_args[2];
|
int positional_args[2];
|
||||||
int positional_count = 0;
|
int positional_count = 0;
|
||||||
|
|||||||
+13
-1
@@ -91,7 +91,19 @@ DirectoryScanner* directory_scanner_create_full(char* root_directory, bool use_m
|
|||||||
scanner->max_size = max_size;
|
scanner->max_size = max_size;
|
||||||
scanner->min_size = min_size;
|
scanner->min_size = min_size;
|
||||||
scanner->follow_symlinks = follow_symlinks;
|
scanner->follow_symlinks = follow_symlinks;
|
||||||
queue_enqueue(scanner->directories, str_dup(root_directory));
|
char* root_copy = str_dup(root_directory);
|
||||||
|
if (root_copy == NULL) {
|
||||||
|
for (int i = 0; i < scanner->include_count; i++)
|
||||||
|
free(scanner->include_patterns[i]);
|
||||||
|
free(scanner->include_patterns);
|
||||||
|
for (int i = 0; i < scanner->exclude_count; i++)
|
||||||
|
free(scanner->exclude_patterns[i]);
|
||||||
|
free(scanner->exclude_patterns);
|
||||||
|
queue_destroy(scanner->directories);
|
||||||
|
free(scanner);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
queue_enqueue(scanner->directories, root_copy);
|
||||||
return scanner;
|
return scanner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -247,10 +247,9 @@ int main(int argc, char* argv[]) {
|
|||||||
server_listen(g_server, handler);
|
server_listen(g_server, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Graceful shutdown: if a signal requested cleanup, delete the server */
|
/* Graceful shutdown: delete the server */
|
||||||
if (g_server_cleanup_requested) {
|
if (g_server_cleanup_requested)
|
||||||
log_message(LOG_LEVEL_INFO, "Shutdown requested, cleaning up");
|
log_message(LOG_LEVEL_INFO, "Shutdown requested, cleaning up");
|
||||||
server_delete(&g_server);
|
server_delete(&g_server);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-8
@@ -82,6 +82,8 @@ void config_parse_ssh_dest(Config* config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void config_delete(Config* config) {
|
void config_delete(Config* config) {
|
||||||
|
if (config == NULL)
|
||||||
|
return;
|
||||||
free(config->version);
|
free(config->version);
|
||||||
free(config->send_directory);
|
free(config->send_directory);
|
||||||
free(config->receive_root_directory);
|
free(config->receive_root_directory);
|
||||||
@@ -260,10 +262,6 @@ Config* config_receive(int file_descriptor) {
|
|||||||
MAX_PATTERN_COUNT);
|
MAX_PATTERN_COUNT);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if ((size_t)ec > SIZE_MAX / sizeof(char*)) {
|
|
||||||
log_message(LOG_LEVEL_ERROR, "Exclude pattern count %d would cause integer overflow", ec);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
config->exclude_count = ec;
|
config->exclude_count = ec;
|
||||||
if (ec > 0) {
|
if (ec > 0) {
|
||||||
config->exclude_patterns = malloc((size_t)ec * sizeof(char*));
|
config->exclude_patterns = malloc((size_t)ec * sizeof(char*));
|
||||||
@@ -293,10 +291,6 @@ Config* config_receive(int file_descriptor) {
|
|||||||
MAX_PATTERN_COUNT);
|
MAX_PATTERN_COUNT);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if ((size_t)ic > SIZE_MAX / sizeof(char*)) {
|
|
||||||
log_message(LOG_LEVEL_ERROR, "Include pattern count %d would cause integer overflow", ic);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
config->include_count = ic;
|
config->include_count = ic;
|
||||||
if (ic > 0) {
|
if (ic > 0) {
|
||||||
config->include_patterns = malloc((size_t)ic * sizeof(char*));
|
config->include_patterns = malloc((size_t)ic * sizeof(char*));
|
||||||
@@ -340,6 +334,16 @@ error:
|
|||||||
free(config->version);
|
free(config->version);
|
||||||
free(config->send_directory);
|
free(config->send_directory);
|
||||||
free(config->receive_root_directory);
|
free(config->receive_root_directory);
|
||||||
|
for (int i = 0; i < config->exclude_count; i++)
|
||||||
|
free(config->exclude_patterns[i]);
|
||||||
|
free(config->exclude_patterns);
|
||||||
|
for (int i = 0; i < config->include_count; i++)
|
||||||
|
free(config->include_patterns[i]);
|
||||||
|
free(config->include_patterns);
|
||||||
|
free(config->tls_cert);
|
||||||
|
free(config->tls_key);
|
||||||
|
free(config->tls_ca);
|
||||||
|
free(config->ssh_destination);
|
||||||
free(config->server_host);
|
free(config->server_host);
|
||||||
free(config);
|
free(config);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
+12
-1
@@ -3,6 +3,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -109,6 +110,9 @@ bool file_load_data(File* file) {
|
|||||||
size_t bytes_read = file_content_to_buffer(file);
|
size_t bytes_read = file_content_to_buffer(file);
|
||||||
if (bytes_read != file->data->size) {
|
if (bytes_read != file->data->size) {
|
||||||
log_message(LOG_LEVEL_ERROR, "Did not read expected amount of bytes from file");
|
log_message(LOG_LEVEL_ERROR, "Did not read expected amount of bytes from file");
|
||||||
|
free(file->data->data);
|
||||||
|
file->data->data = NULL;
|
||||||
|
file->data->size = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -140,11 +144,13 @@ static bool file_send_streaming(File* file, int file_descriptor) {
|
|||||||
if (ferror(fp)) {
|
if (ferror(fp)) {
|
||||||
perror("Read error during streaming");
|
perror("Read error during streaming");
|
||||||
}
|
}
|
||||||
|
send_status(file_descriptor, STATUS_ERROR);
|
||||||
free(buf);
|
free(buf);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!send_n_data(file_descriptor, buf, nread)) {
|
if (!send_n_data(file_descriptor, buf, nread)) {
|
||||||
|
send_status(file_descriptor, STATUS_ERROR);
|
||||||
free(buf);
|
free(buf);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return false;
|
return false;
|
||||||
@@ -626,8 +632,13 @@ bool file_send_sendfile(File* file, int file_descriptor, bool use_metadata, int
|
|||||||
|
|
||||||
off_t offset = 0;
|
off_t offset = 0;
|
||||||
while ((unsigned long long)offset < file_size) {
|
while ((unsigned long long)offset < file_size) {
|
||||||
ssize_t sent = sendfile(file_descriptor, fd, &offset, file_size - offset);
|
size_t send_count = (size_t)(file_size - (unsigned long long)offset);
|
||||||
|
if ((unsigned long long)send_count != file_size - (unsigned long long)offset)
|
||||||
|
send_count = SIZE_MAX;
|
||||||
|
ssize_t sent = sendfile(file_descriptor, fd, &offset, send_count);
|
||||||
if (sent == -1) {
|
if (sent == -1) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
perror("sendfile failed");
|
perror("sendfile failed");
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ void log_message(LogLevel log_level, const char* format, ...) {
|
|||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
struct tm result_buf;
|
struct tm result_buf;
|
||||||
const struct tm* t = localtime_r(&now, &result_buf);
|
const struct tm* t = localtime_r(&now, &result_buf);
|
||||||
|
if (t == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
fprintf(stderr, "%04d-%02d-%02d %02d:%02d:%02d [%s]: ", t->tm_year + 1900, t->tm_mon + 1,
|
fprintf(stderr, "%04d-%02d-%02d %02d:%02d:%02d [%s]: ", t->tm_year + 1900, t->tm_mon + 1,
|
||||||
t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, log_level_strings[log_level]);
|
t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, log_level_strings[log_level]);
|
||||||
|
|||||||
@@ -20,6 +20,9 @@
|
|||||||
* serialized as fixed-width integers.
|
* serialized as fixed-width integers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Size of metadata fields on wire, excluding the int32_t `present` field that
|
||||||
|
* is always sent first. The total wire size for present metadata is
|
||||||
|
* sizeof(int32_t) + FILE_METADATA_WIRE_SIZE (32 bytes on most platforms). */
|
||||||
#define FILE_METADATA_WIRE_SIZE (sizeof(int32_t) * 3 + sizeof(int64_t) * 2)
|
#define FILE_METADATA_WIRE_SIZE (sizeof(int32_t) * 3 + sizeof(int64_t) * 2)
|
||||||
|
|
||||||
void metadata_to_buf(char** buf, const FileMetadata* m);
|
void metadata_to_buf(char** buf, const FileMetadata* m);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
static __thread int io_read_fd = -1;
|
static __thread int io_read_fd = -1;
|
||||||
static __thread int io_write_fd = -1;
|
static __thread int io_write_fd = -1;
|
||||||
static SSL* io_ssl = NULL;
|
static __thread SSL* io_ssl = NULL;
|
||||||
|
|
||||||
static unsigned long long io_bwlimit = 0;
|
static unsigned long long io_bwlimit = 0;
|
||||||
static long long bw_tokens = 0;
|
static long long bw_tokens = 0;
|
||||||
|
|||||||
@@ -119,10 +119,13 @@ Client* client_connect_ssh(const char* destination, int port) {
|
|||||||
close(sv[1]);
|
close(sv[1]);
|
||||||
|
|
||||||
char ssh_user[512];
|
char ssh_user[512];
|
||||||
|
int needed;
|
||||||
if (r.user && r.user[0] != '\0')
|
if (r.user && r.user[0] != '\0')
|
||||||
snprintf(ssh_user, sizeof(ssh_user), "%s@%s", r.user, r.host);
|
needed = snprintf(ssh_user, sizeof(ssh_user), "%s@%s", r.user, r.host);
|
||||||
else
|
else
|
||||||
snprintf(ssh_user, sizeof(ssh_user), "%s", r.host);
|
needed = snprintf(ssh_user, sizeof(ssh_user), "%s", r.host);
|
||||||
|
if ((size_t)needed >= sizeof(ssh_user))
|
||||||
|
fprintf(stderr, "Warning: ssh_user string truncated\n");
|
||||||
|
|
||||||
size_t ssh_argv_max = 32;
|
size_t ssh_argv_max = 32;
|
||||||
char** ssh_argv = calloc(ssh_argv_max, sizeof(char*));
|
char** ssh_argv = calloc(ssh_argv_max, sizeof(char*));
|
||||||
|
|||||||
Reference in New Issue
Block a user