Line data Source code
1 : #include "precizer.h"
2 :
3 : /**
4 : *
5 : * Calculate SHA512 cryptographic hash of a file
6 : *
7 : */
8 1092 : Return sha512sum(
9 : const char *path,
10 : const size_t path_size,
11 : memory *file_buffer,
12 : unsigned char *sha512,
13 : sqlite3_int64 *offset,
14 : SHA512_Context *mdContext,
15 : bool *wrong_file_type)
16 : {
17 : /// The status that will be passed to return() before exiting.
18 : /// By default, the function worked without errors.
19 1092 : Return status = SUCCESS;
20 :
21 1092 : if(file_buffer->length == 0)
22 : {
23 0 : slog(ERROR,"Invalid buffer size: %ld bytes\n",file_buffer->length);
24 0 : provide(FAILURE);
25 : }
26 :
27 1092 : char *absolute_path = NULL;
28 :
29 1092 : FILE *fileptr = fopen(path,"rb");
30 :
31 1092 : if(fileptr == NULL)
32 : {
33 : // No read permission
34 1084 : if(errno == EACCES)
35 : {
36 0 : provide(status);
37 : }
38 :
39 1084 : status = path_absolute_from_relative(&absolute_path,path,path_size);
40 :
41 1084 : if(absolute_path == NULL || SUCCESS != status)
42 : {
43 0 : slog(ERROR,"Can't constructs an absolute path from the base directory %s and a relative path %s\n",config->running_dir,path);
44 :
45 0 : if(absolute_path != NULL)
46 : {
47 0 : free(absolute_path);
48 : }
49 0 : provide(status);
50 : }
51 :
52 1084 : fileptr = fopen(absolute_path,"rb");
53 :
54 1084 : if(fileptr == NULL)
55 : {
56 : // No read permission
57 0 : if(errno == EACCES)
58 : {
59 0 : free(absolute_path);
60 0 : provide(status);
61 : }
62 :
63 0 : slog(ERROR,"Can open the file using neither relative %s nor absolute %s path with errno: %d\n",path,absolute_path,errno);
64 0 : free(absolute_path);
65 0 : provide(FAILURE);
66 : }
67 : }
68 :
69 : // It moves the file pointer "offset" bytes from the beginning of the file
70 1092 : if(fseek(fileptr,*offset,SEEK_SET) != 0)
71 : {
72 : /* Looks like the wrong file type.
73 : Doesn't need to return FAILURE status */
74 0 : *wrong_file_type = true;
75 0 : free(absolute_path);
76 0 : fclose(fileptr);
77 0 : provide(status);
78 : }
79 :
80 1092 : bool loop_was_interrupted = false;
81 :
82 1092 : if(*offset == 0)
83 : {
84 1092 : if(sha512_init(mdContext) == 1)
85 : {
86 0 : slog(ERROR,"SHA512 initialization failed\n");
87 0 : free(absolute_path);
88 0 : fclose(fileptr);
89 0 : provide(FAILURE);
90 : }
91 : }
92 :
93 1092 : if(config->dry_run == false)
94 : {
95 1056 : unsigned char *buffer = rawdata(file_buffer);
96 :
97 1056 : size_t len = 0;
98 :
99 : while(true)
100 : {
101 : /* Interrupt the loop smoothly */
102 : /* Interrupt when Ctrl+C */
103 2112 : if(global_interrupt_flag == true)
104 : {
105 0 : loop_was_interrupted = true;
106 0 : break;
107 : }
108 :
109 2112 : len = fread(buffer,sizeof(unsigned char),file_buffer->length,fileptr);
110 :
111 2112 : if(len == 0)
112 : {
113 1056 : if(ferror(fileptr))
114 : {
115 0 : slog(ERROR,"Error reading file %s\n",path);
116 0 : status = FAILURE;
117 : }
118 :
119 1056 : break;
120 : }
121 :
122 1056 : if(SUCCESS == status)
123 : {
124 1056 : if(sha512_update(mdContext,buffer,len) == 1)
125 : {
126 0 : slog(ERROR,"SHA512 update failed\n");
127 0 : status = FAILURE;
128 0 : break;
129 : }
130 :
131 1056 : *offset += (sqlite3_int64)len;
132 : }
133 : }
134 : }
135 :
136 1092 : if(fclose(fileptr) != 0)
137 : {
138 0 : slog(ERROR,"Error closing file %s\n",path);
139 : }
140 :
141 1092 : free(absolute_path);
142 :
143 1092 : if(SUCCESS == status)
144 : {
145 1092 : if(loop_was_interrupted == false)
146 : {
147 1092 : *offset = 0;
148 :
149 1092 : if(sha512_final(mdContext,sha512) == 1)
150 : {
151 0 : slog(ERROR,"SHA512 finalization failed\n");
152 0 : status = FAILURE;
153 : }
154 : }
155 : }
156 :
157 : #if 0
158 :
159 : for(size_t i = 0; i < SHA512_DIGEST_LENGTH; i++)
160 : {
161 : printf("%02x",sha512[i]);
162 : }
163 : putchar('\n');
164 :
165 : #endif
166 :
167 1092 : provide(status);
168 : }
|