2021-05-15 19:18:42 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
|
|
#include "file_t.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the size of the file by its file descriptor
|
|
|
|
* @param fd file descriptor
|
|
|
|
* @return file size in bytes
|
|
|
|
*/
|
|
|
|
static unsigned long
|
|
|
|
get_size_by_fd(int fd);
|
|
|
|
|
|
|
|
static unsigned long
|
|
|
|
get_size_by_fd(int fd)
|
|
|
|
{
|
|
|
|
struct stat statbuf;
|
|
|
|
fstat(fd, &statbuf);
|
|
|
|
return statbuf.st_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
file_t*
|
2021-05-31 22:07:06 +02:00
|
|
|
file_init(const char *filename, filepath_t FILEPATH, exception_t *e)
|
2021-05-15 19:18:42 +02:00
|
|
|
{
|
2021-05-31 22:07:06 +02:00
|
|
|
char *path;
|
|
|
|
switch (FILEPATH) {
|
|
|
|
case FILEPATH_ABSOLUTE: {
|
|
|
|
path = (char*) filename; break;
|
|
|
|
}
|
|
|
|
case FILEPATH_RELATIVE: path = (char*) filename; break;
|
|
|
|
}
|
|
|
|
|
2021-05-15 19:18:42 +02:00
|
|
|
/* Checks if the file path can be opened. */
|
2021-05-31 22:07:06 +02:00
|
|
|
if (open(path, O_RDONLY) < 0)
|
2021-05-15 19:18:42 +02:00
|
|
|
{
|
|
|
|
e->type = NO_FILE;
|
2021-05-31 22:07:06 +02:00
|
|
|
e->msg = path;
|
2021-05-15 19:18:42 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
file_t *f;
|
2021-06-01 00:08:30 +02:00
|
|
|
f = malloc(sizeof(file_t));
|
2021-05-31 22:07:06 +02:00
|
|
|
f->name = (char*) path;
|
2021-05-15 19:18:42 +02:00
|
|
|
f->hash_str = NULL;
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
file_close(file_t *f)
|
|
|
|
{
|
2021-05-31 22:07:06 +02:00
|
|
|
if (f->hash_str != NULL) free(f->hash_str);
|
2021-05-15 19:18:42 +02:00
|
|
|
free(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char*
|
|
|
|
file_md5_gen(file_t *f, exception_t *e)
|
|
|
|
{
|
|
|
|
int file_descript;
|
|
|
|
unsigned long file_size;
|
|
|
|
unsigned char *file_buffer;
|
|
|
|
|
|
|
|
file_descript = open(f->name, O_RDONLY);
|
|
|
|
|
|
|
|
/* Grabs the size of file */
|
|
|
|
file_size = get_size_by_fd(file_descript);
|
|
|
|
|
|
|
|
/* Generates the buffer */
|
|
|
|
file_buffer = (unsigned char*) mmap(0, file_size, PROT_READ, MAP_SHARED, file_descript, 0);
|
|
|
|
|
|
|
|
/* Computes the MD5 checksum to result */
|
2021-06-01 00:08:30 +02:00
|
|
|
if (MD5(file_buffer, file_size, f->hash) == NULL) {
|
|
|
|
e->type = MD5SUM_GEN_FAIL;
|
|
|
|
e->msg = "No hash!";
|
|
|
|
}
|
|
|
|
|
2021-05-15 19:18:42 +02:00
|
|
|
/* Removes fime_buffer and file_size */
|
|
|
|
munmap(file_buffer, file_size);
|
2021-06-01 00:08:30 +02:00
|
|
|
|
2021-05-15 19:18:42 +02:00
|
|
|
return f->hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
char*
|
|
|
|
file_md5_str(file_t *f, exception_t *e)
|
|
|
|
{
|
|
|
|
static const char digits[] = "0123456789abcdef";
|
2021-06-01 00:08:30 +02:00
|
|
|
f->hash_str = malloc (2*MD5_DIGEST_LENGTH+1);
|
|
|
|
size_t si = 0;
|
|
|
|
for (size_t i = si; i < MD5_DIGEST_LENGTH; i++)
|
2021-05-15 19:18:42 +02:00
|
|
|
{
|
2021-06-01 00:08:30 +02:00
|
|
|
f->hash_str[si++] = digits[f->hash[i] / MD5_DIGEST_LENGTH];
|
|
|
|
f->hash_str[si++] = digits[f->hash[i] % MD5_DIGEST_LENGTH];
|
2021-05-15 19:18:42 +02:00
|
|
|
}
|
|
|
|
|
2021-06-01 00:08:30 +02:00
|
|
|
f->hash_str[2*MD5_DIGEST_LENGTH] = '\0';
|
2021-05-15 19:18:42 +02:00
|
|
|
return f->hash_str;
|
|
|
|
}
|