-
Notifications
You must be signed in to change notification settings - Fork 0
/
backup.c
111 lines (88 loc) · 2.35 KB
/
backup.c
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
#include "backup.h"
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define BUFFER_SIZE 512
#define DATA_PATH "/.Backup/data/"
#define METADATA_PATH "/.Backup/metadata/"
int backup(MESSAGE msg) {
int err;
char root_dir[PATH_SIZE], ln_dir[PATH_SIZE], *hash, *home, *f_name;
home = getenv("HOME");
f_name = get_file_name(msg->file_path);
strncpy(root_dir, home, PATH_SIZE);
strncat(root_dir, DATA_PATH, PATH_SIZE);
strncpy(ln_dir, root_dir, PATH_SIZE);
strncat(root_dir, f_name, PATH_SIZE);
//Gerar uma hash a partir do ficheiro
hash = generate_hash(root_dir);
if (!hash)
return 1;
strncat(ln_dir, hash, PATH_SIZE);
if (access(ln_dir, F_OK) == -1) {
rename(root_dir, ln_dir);
//Comprime o ficheiro na raiz com o nome hash
err = compress_file(ln_dir);
if (err) {
free(hash);
return 1;
}
} else remove(root_dir);
strncpy(root_dir, home, PATH_SIZE);
strncat(root_dir, "/.Backup/data/", PATH_SIZE);
strncat(root_dir, hash, PATH_SIZE);
strncpy(ln_dir, home, PATH_SIZE);
strncat(ln_dir, "/.Backup/metadata/", PATH_SIZE);
strncat(ln_dir, f_name, PATH_SIZE);
//Cria symlink .Backup/data/digest -> .Backup/metadata/ficheiro
symlink(root_dir, ln_dir);
strncpy(root_dir, msg->file_path, PATH_SIZE);
strncpy(ln_dir, home, PATH_SIZE);
strncat(ln_dir, "/.Backup/paths/", PATH_SIZE);
strncat(ln_dir, f_name, PATH_SIZE);
//Cria symlink em /paths/
symlink(root_dir, ln_dir);
free(hash);
return 0;
}
int compress_file(char* file_path) {
char data_dir[PATH_SIZE];
int st=0;
if (!fork()) {
execlp("gzip", "gzip", file_path, NULL);
perror("Erro 1 ao tentar comprimir ficheiro");
_exit(1);
}
sprintf(data_dir, "%s.gz", file_path);
wait(&st);
st = WEXITSTATUS(st);
if (st != 0) return st;
st = rename(data_dir, file_path);
return st;
}
char* generate_hash(char *file_path) {
char sha1sum[BUFFER_SIZE], *hash, *ret = NULL;
int pp[2], status;
pipe(pp);
if (!fork()) {
close(pp[0]);
dup2(pp[1], 1);
execlp("sha1sum", "sha1sum", file_path, NULL);
close(pp[1]);
perror("Erro ao tentar calcular hash");
_exit(1);
}
wait(&status);
status = WEXITSTATUS(status);
if (status != 0) return ret;
close(pp[1]);
read(pp[0], sha1sum, PATH_SIZE);
close(pp[0]);
hash = strtok(sha1sum, " ");
ret = malloc(strlen(hash) + 1);
strcpy(ret, hash);
return ret;
}