~ruther/CTU-FEE-B0B35APO-Semestral-project

ref: 57bf90d2b8e5261a13e04195c9b9832c60369509 CTU-FEE-B0B35APO-Semestral-project/file-browser/src/local_file_connectors.c -rw-r--r-- 3.6 KiB
57bf90d2 — František Boháček fix: get corret errno on file copy 3 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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.payload.local.path, destination)];
  path_join(second_state.payload.local.path, 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 = FILOPER_SUCCESS;
  if (!feof(src_file) && ferror(src_file)) {
    error = file_operation_error_from_errno(errno);
  } else if (ferror(dst_file)) {
    error = file_operation_error_from_errno(errno);
  }

  fclose(src_file);
  fclose(dst_file);
  return error;
}

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.payload.local.path, destination)];
  path_join(second_state.payload.local.path, 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},
};
Do not follow this link