From dfd08742c0a885475452c550226a5a36d220a205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Wed, 23 Jun 2021 12:00:13 +0200 Subject: [PATCH] feat: add copy and move operations for local filesystem --- file-browser/include/local_file_connectors.h | 14 +++ file-browser/src/local_file_connectors.c | 115 +++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 file-browser/include/local_file_connectors.h create mode 100644 file-browser/src/local_file_connectors.c diff --git a/file-browser/include/local_file_connectors.h b/file-browser/include/local_file_connectors.h new file mode 100644 index 0000000000000000000000000000000000000000..8359315ff3cd7480ad18b4c542e76969b3048c36 --- /dev/null +++ b/file-browser/include/local_file_connectors.h @@ -0,0 +1,14 @@ +#ifndef __LOCAL_FILE_CONNECTORS_H__ +#define __LOCAL_FILE_CONNECTORS_H__ + +#include "file_access.h" + +file_operation_error_t local_connector_file_copy( + fileaccess_connector_t *connector, fileaccess_state_t first_state, + fileaccess_state_t second_state, file_t *file, char *destination); + +file_operation_error_t local_connector_file_move( + fileaccess_connector_t *connector, fileaccess_state_t first_state, + fileaccess_state_t second_state, file_t *file, char *destination); + +#endif // __LOCAL_FILE_CONNECTORS_H__ diff --git a/file-browser/src/local_file_connectors.c b/file-browser/src/local_file_connectors.c new file mode 100644 index 0000000000000000000000000000000000000000..5a4e216ad885cd52deab3e24d25d19064c193591 --- /dev/null +++ b/file-browser/src/local_file_connectors.c @@ -0,0 +1,115 @@ +#include "local_file_connectors.h" +#include "file_access.h" +#include "local_file_utils.h" +#include "path.h" +#include +#include + +#define BUFFER_SIZE 1024 + +file_operation_error_t local_connector_file_copy( + fileaccess_connector_t *connector, fileaccess_state_t first_state, + fileaccess_state_t second_state, file_t *file, char *destination) { + char src_path[file_get_full_path_memory_size(first_state, file->directory, + file)]; + file_get_full_path(first_state, file->directory, file, src_path); + + char dst_path[path_join_memory_size(second_state.state, destination)]; + path_join(second_state.state, destination, dst_path); + + // TODO: copy folders + + FILE *src_file = fopen(src_path, "r"); + if (src_file == NULL) { + return file_operation_error_from_errno(errno); + } + FILE *dst_file = fopen(dst_path, "w"); + if (dst_file == NULL) { + fclose(src_file); + return file_operation_error_from_errno(errno); + } + + while (!feof(src_file) && !ferror(src_file) && !ferror(dst_file)) { + char buffer[BUFFER_SIZE]; + unsigned long in = fread(buffer, sizeof(char), BUFFER_SIZE, src_file); + if (in == 0) { + continue; + } + fwrite(buffer, sizeof(char), in, dst_file); + } + + file_operation_error_t error; + if (!feof(src_file) && ferror(src_file)) { + error = file_operation_error_from_errno(ferror(src_file)); + } else if (ferror(dst_file)) { + error = file_operation_error_from_errno(ferror(dst_file)); + } + + fclose(src_file); + fclose(dst_file); + return FILOPER_SUCCESS; +} + +file_operation_error_t local_connector_file_move( + fileaccess_connector_t *connector, fileaccess_state_t first_state, + fileaccess_state_t second_state, file_t *file, char *destination) { + file_operation_error_t error = FILOPER_SUCCESS; + char src_path[file_get_full_path_memory_size(first_state, file->directory, + file)]; + char dst_path[path_join_memory_size(second_state.state, destination)]; + path_join(second_state.state, destination, dst_path); + + int status = rename(src_path, dst_path); + if (status == 0) { + return error; + } + + if (errno == EXDEV) { + // if rename does not work + file_get_full_path(first_state, file->directory, file, src_path); + + error = connector->copy(connector, first_state, second_state, file, + destination); + if (error == FILOPER_SUCCESS) { + if (file->type == FT_FOLDER) { + error = directory_delete(src_path); + } else { + error = file_delete(src_path); + } + } + } else { + error = file_operation_error_from_errno(errno); + } + + return error; +} + +fileaccess_connector_t fileaccess_connectors[(FA_COUNT - 1) * FA_COUNT] = { + {.first = &local_file_access, + .second = &temp_file_access, + .move = local_connector_file_move, + .copy = local_connector_file_copy}, + + {.first = &temp_file_access, + .second = &local_file_access, + .move = local_connector_file_move, + .copy = local_connector_file_copy}, + + {.first = &local_file_access, + .second = &extern_file_access, + .move = local_connector_file_move, + .copy = local_connector_file_copy}, + {.first = &extern_file_access, + .second = &local_file_access, + .move = local_connector_file_move, + .copy = local_connector_file_copy}, + + {.first = &extern_file_access, + .second = &temp_file_access, + .move = local_connector_file_move, + .copy = local_connector_file_copy}, + {.first = &temp_file_access, + .second = &extern_file_access, + .move = local_connector_file_move, + .copy = local_connector_file_copy}, +};