Fix incremental-sync review: sendfile_no_path, reject -s+incremental, no data mutation, auto -M, STATUS_ERROR handling, PROTOCOL_VERSION bump
This commit is contained in:
@@ -187,6 +187,16 @@ int main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (config->use_incremental && config->use_chunk_serialization) {
|
||||
fprintf(stderr, "Error: --incremental is not supported with -s (chunk serialization)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (config->use_incremental && !config->use_metadata) {
|
||||
log_message(LOG_LEVEL_INFO, "Enabling metadata preservation for --incremental");
|
||||
config->use_metadata = true;
|
||||
}
|
||||
|
||||
if (config->use_multithreading)
|
||||
return send_files_multithreaded(config);
|
||||
return send_files(config);
|
||||
|
||||
@@ -41,14 +41,17 @@ int send_chunk(Client *client, Chunk *chunk, Config *config) {
|
||||
if (!send_n_data(client->file_descriptor, &mtime, sizeof(mtime))) return -1;
|
||||
Status s;
|
||||
if (!receive_status(client->file_descriptor, &s)) return -1;
|
||||
if (s == STATUS_ERROR) { log_message(LOG_LEVEL_ERROR, "Server reported error for file"); return -1; }
|
||||
if (s == STATUS_OK) continue;
|
||||
if (s != STATUS_NEXT) return -1;
|
||||
if (s != STATUS_NEXT) { log_message(LOG_LEVEL_ERROR, "Unexpected server status"); return -1; }
|
||||
if (!file_send_sendfile_no_path(chunk->items[i], client->file_descriptor, config->use_metadata))
|
||||
return -1;
|
||||
} else {
|
||||
if (!send_status(client->file_descriptor, STATUS_NEXT)) return -1;
|
||||
}
|
||||
if (!file_send_sendfile(chunk->items[i], client->file_descriptor, config->use_metadata))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < chunk->element_count; i++) {
|
||||
if (config->use_incremental) {
|
||||
@@ -60,8 +63,9 @@ int send_chunk(Client *client, Chunk *chunk, Config *config) {
|
||||
if (!send_n_data(client->file_descriptor, &mtime, sizeof(mtime))) return -1;
|
||||
Status s;
|
||||
if (!receive_status(client->file_descriptor, &s)) return -1;
|
||||
if (s == STATUS_ERROR) { log_message(LOG_LEVEL_ERROR, "Server reported error for file"); return -1; }
|
||||
if (s == STATUS_OK) continue;
|
||||
if (s != STATUS_NEXT) return -1;
|
||||
if (s != STATUS_NEXT) { log_message(LOG_LEVEL_ERROR, "Unexpected server status"); return -1; }
|
||||
if (!file_send_single_calls_no_path(chunk->items[i], client->file_descriptor,
|
||||
config->use_metadata,
|
||||
config->use_compression ? config->compression_level : 0))
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ typedef struct Config {
|
||||
bool use_incremental;
|
||||
} Config;
|
||||
|
||||
#define PROTOCOL_VERSION "1.0.0"
|
||||
#define PROTOCOL_VERSION "1.1.0"
|
||||
#define DEFAULT_CHUNK_SIZE (10 * 1024 * 1024)
|
||||
|
||||
Config *config_create(char *version, char *send_directory,
|
||||
|
||||
+57
-13
@@ -97,37 +97,81 @@ bool file_load_data(File *file) {
|
||||
}
|
||||
|
||||
bool file_send_single_calls_no_path(File *file, int file_descriptor, bool use_metadata, int compression_level) {
|
||||
Data *data_to_send = file->data;
|
||||
Data *compressed_data = NULL;
|
||||
if (compression_level > 0) {
|
||||
Data *compressed_data = data_compress(file->data, compression_level);
|
||||
compressed_data = data_compress(file->data, compression_level);
|
||||
if (compressed_data == NULL) {
|
||||
log_message(LOG_LEVEL_ERROR, "Failed to compress file data");
|
||||
return false;
|
||||
}
|
||||
data_destroy(file->data);
|
||||
file->data = compressed_data;
|
||||
data_to_send = compressed_data;
|
||||
}
|
||||
if (use_metadata && !metadata_send(file_descriptor, file->metadata)) {
|
||||
data_destroy(compressed_data);
|
||||
return false;
|
||||
}
|
||||
if (!send_data(file_descriptor, data_to_send)) {
|
||||
data_destroy(compressed_data);
|
||||
return false;
|
||||
}
|
||||
data_destroy(compressed_data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool file_send_sendfile_no_path(File *file, int file_descriptor, bool use_metadata) {
|
||||
if (use_metadata && !metadata_send(file_descriptor, file->metadata)) return false;
|
||||
if (!send_data(file_descriptor, file->data)) return false;
|
||||
|
||||
int fd = open(file->path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("Could not open file for sendfile");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long long file_size = file->data->size;
|
||||
if (!send_n_data(file_descriptor, &file_size, sizeof(unsigned long long))) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
off_t offset = 0;
|
||||
while (offset < file_size) {
|
||||
ssize_t sent = sendfile(file_descriptor, fd, &offset, file_size - offset);
|
||||
if (sent == -1) {
|
||||
perror("sendfile failed");
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool file_send_single_calls(File *file, int file_descriptor, bool use_metadata, int compression_level) {
|
||||
Data *data_to_send = file->data;
|
||||
Data *compressed_data = NULL;
|
||||
if (compression_level > 0) {
|
||||
Data *compressed_data = data_compress(file->data, compression_level);
|
||||
compressed_data = data_compress(file->data, compression_level);
|
||||
if (compressed_data == NULL) {
|
||||
log_message(LOG_LEVEL_ERROR, "Failed to compress file data");
|
||||
return false;
|
||||
}
|
||||
data_destroy(file->data);
|
||||
if (compressed_data == NULL) {
|
||||
log_message(LOG_LEVEL_ERROR, "Compression failed in file_send_single_calls");
|
||||
exit(EXIT_FAILURE);
|
||||
data_to_send = compressed_data;
|
||||
}
|
||||
file->data = compressed_data;
|
||||
if (!send_str(file_descriptor, file->path)) {
|
||||
data_destroy(compressed_data);
|
||||
return false;
|
||||
}
|
||||
if (!send_str(file_descriptor, file->path)) return false;
|
||||
if (use_metadata && !metadata_send(file_descriptor, file->metadata)) return false;
|
||||
if (!send_data(file_descriptor, file->data)) return false;
|
||||
if (use_metadata && !metadata_send(file_descriptor, file->metadata)) {
|
||||
data_destroy(compressed_data);
|
||||
return false;
|
||||
}
|
||||
if (!send_data(file_descriptor, data_to_send)) {
|
||||
data_destroy(compressed_data);
|
||||
return false;
|
||||
}
|
||||
data_destroy(compressed_data);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ File *file_receive(Config *config, int file_descriptor);
|
||||
bool file_send_single_calls(File *file, int file_descriptor, bool use_metadata, int compression_level);
|
||||
bool file_send_single_calls_no_path(File *file, int file_descriptor, bool use_metadata, int compression_level);
|
||||
bool file_send_sendfile(File *file, int file_descriptor, bool use_metadata);
|
||||
bool file_send_sendfile_no_path(File *file, int file_descriptor, bool use_metadata);
|
||||
size_t file_content_to_buffer(File *file);
|
||||
FileMetadata *file_metadata_create(struct stat *stats);
|
||||
void file_metadata_destroy(void *metadata);
|
||||
|
||||
Reference in New Issue
Block a user