@@ 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__
@@ 0,0 1,115 @@
+#include "local_file_connectors.h"
+#include "file_access.h"
+#include "local_file_utils.h"
+#include "path.h"
+#include <stdio.h>
+#include <errno.h>
+
+#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},
+};