-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfile_handler.c
More file actions
230 lines (195 loc) · 6.55 KB
/
Copy pathfile_handler.c
File metadata and controls
230 lines (195 loc) · 6.55 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <stdint.h>
#include <string.h>
#include <libgen.h>
#include <openssl/md5.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "file_handler.h"
#include "file_modifier.h"
#include "backup_manager.h"
#define HASH_TABLE_SIZE 4096
#define MAX_PATH 1024
void reset_str(char *str)
{ // Vide la chaine de caractère
while (*str != '\0')
{
*str = '\0';
++str;
}
}
void compute_md5_file(const char *filename, unsigned char *md5, unsigned int *md5_len)
{ // genere un md5 a partir d'un fichier
EVP_MD_CTX *context = EVP_MD_CTX_new();
if (!context)
{
fprintf(stderr, "Erreur : impossible d'initialiser EVP_MD_CTX\n");
exit(1);
}
if (EVP_DigestInit_ex(context, EVP_md5(), NULL) != 1)
{
fprintf(stderr, "Erreur : EVP_DigestInit_ex a échoué\n");
EVP_MD_CTX_free(context);
exit(1);
}
EVP_DigestUpdate(context, filename, strlen(filename));
if (EVP_DigestFinal_ex(context, md5, md5_len) != 1)
{
fprintf(stderr, "Erreur : EVP_DigestFinal_ex a échoué\n");
EVP_MD_CTX_free(context);
exit(1);
}
EVP_MD_CTX_free(context);
}
void compute_md5_chunk(char *data, size_t taille, char *md5_string)
{// genère un md5 à partir d'un chunk
EVP_MD_CTX *ctx;
unsigned char md5_digest[EVP_MAX_MD_SIZE];
unsigned int md5_length;
ctx = EVP_MD_CTX_new();
if (!ctx)
{
fprintf(stderr, "Erreur : impossible d'initialiser EVP_MD_CTX\n");
return;
}
if (EVP_DigestInit_ex(ctx, EVP_md5(), NULL) != 1)
{
fprintf(stderr, "Erreur : EVP_DigestInit_ex a échoué\n");
EVP_MD_CTX_free(ctx);
return;
}
if (EVP_DigestUpdate(ctx, data, taille) != 1)
{
fprintf(stderr, "Erreur : EVP_DigestUpdate a échoué\n");
EVP_MD_CTX_free(ctx);
return;
}
if (EVP_DigestFinal_ex(ctx, md5_digest, &md5_length) != 1)
{
fprintf(stderr, "Erreur : EVP_DigestFinal_ex a échoué\n");
EVP_MD_CTX_free(ctx);
return;
}
EVP_MD_CTX_free(ctx);
for (unsigned int i = 0; i < md5_length; i++)
{
sprintf(&md5_string[i * 2], "%02x", md5_digest[i]);
}
md5_string[md5_length * 2] = '\0';
}
int compute_chunk(char *nom_fichier, char *path, Chunk *chunks)
{
FILE *fichier_entree = fopen(nom_fichier, "rb");
if (fichier_entree == NULL)
{
perror("Erreur lors de l'ouverture du fichier d'entrée");
return -1;
}
char chunk_data[10][4096] = {0}; // Tableau pour stocker les données des chunks
int index_data = 0; // Index pour les chunks
int chunk_index = 0; // Index pour parcourir le contenu du fichier
char *contenu = read_file(nom_fichier); // Lire le contenu du fichier
if (contenu == NULL)
{
perror("Erreur lors de la lecture du fichier");
fclose(fichier_entree);
return -1;
}
unsigned char md5[EVP_MAX_MD_SIZE];
unsigned int md5_len;
compute_md5_file(path, md5, &md5_len); // Calculer le MD5 du chemin
while (contenu[chunk_index] != '\0')
{
if (chunk_index % 4096 == 0 && chunk_index != 0)
{
// Si un chunk est complet, le stocker dans le tableau de chunks
chunks[index_data].index = index_data + 1;
chunks[index_data].version = 1;
chunks[index_data].data = strdup(chunk_data[index_data]);
compute_md5_chunk(chunk_data[index_data], strlen(chunk_data[index_data]), chunks[index_data].MD5);
memset(chunk_data[index_data], 0, sizeof(chunk_data[index_data]));
index_data++;
}
strncat(chunk_data[index_data], &contenu[chunk_index], 1); // Ajouter un caractère au chunk courant
chunk_index++;
}
if (chunk_index % 4096 != 0)
{
// Si le dernier chunk n'est pas complet, le stocker également
chunks[index_data].index = index_data + 1;
chunks[index_data].version = 1;
chunks[index_data].data = strdup(chunk_data[index_data]);
compute_md5_chunk(chunk_data[index_data], strlen(chunk_data[index_data]), chunks[index_data].MD5);
}
fclose(fichier_entree);
free(contenu);
return index_data + 1; // Retourner le nombre de chunks créés
}
char* get_md5_of_directory_name(const char *dir_path)
{//génère un md5 à partir du nom d'un répertoire
unsigned char md5[EVP_MAX_MD_SIZE];
unsigned int md5_len;
char *md5_string = malloc(33);
if (!md5_string) {
perror("Erreur lors de l'allocation de mémoire pour md5_string");
return NULL;
}
compute_md5_file(dir_path, md5, &md5_len);
for (unsigned int i = 0; i < md5_len; i++) {
sprintf(&md5_string[i * 2], "%02x", md5[i]);
}
md5_string[md5_len * 2] = '\0';
return md5_string;
}
void compute_md5_case(const char *dir_path, unsigned char *md5_out) {
DIR *dir = opendir(dir_path);
if (!dir) {
perror("Erreur lors de l'ouverture du répertoire");
return;
}
EVP_MD_CTX *md5_ctx = EVP_MD_CTX_new();
if (!md5_ctx) {
perror("Erreur lors de la création du contexte EVP");
closedir(dir);
return;
}
if (EVP_DigestInit_ex(md5_ctx, EVP_md5(), NULL) != 1) {
perror("Erreur lors de l'initialisation du contexte MD5");
EVP_MD_CTX_free(md5_ctx);
closedir(dir);
return;
}
struct dirent *entry;
char full_path[MAX_PATH];
char **file_names = malloc(sizeof(char*) * 1000);
int file_count = 0;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name);
struct stat st;
if (stat(full_path, &st) == 0) {
file_names[file_count] = strdup(entry->d_name);
file_count++;
}
}
qsort(file_names, file_count, sizeof(char*), (int (*)(const void*, const void*))strcmp);
for (int i = 0; i < file_count; i++) {
EVP_DigestUpdate(md5_ctx, file_names[i], strlen(file_names[i]));
snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, file_names[i]);
struct stat st;
if (stat(full_path, &st) == 0 && S_ISDIR(st.st_mode)) {
compute_md5_case(full_path, md5_out);
}
free(file_names[i]);
}
unsigned int len = EVP_MD_size(EVP_md5());
EVP_DigestFinal_ex(md5_ctx, md5_out, &len);
EVP_MD_CTX_free(md5_ctx);
closedir(dir);
free(file_names);
}