116 lines
2.4 KiB
C
116 lines
2.4 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <openssl/md5.h> /* md5sum */
|
|
#include <fcntl.h>
|
|
#include <sys/mman.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <limits.h>
|
|
#include <glib.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*
|
|
file_init(const char *filename, exception_t *e, const char *env)
|
|
{
|
|
GString *abspath = g_string_new (NULL);
|
|
if (env != NULL)
|
|
{
|
|
char *envpath;
|
|
size_t sizehome, sizepath;
|
|
envpath = getenv (env);
|
|
sizehome = strlen(envpath);
|
|
sizepath = strlen(filename);
|
|
abspath = malloc(sizehome + sizepath + 2);
|
|
strcpy (abspath, envpath);
|
|
strcat (abspath, "/");
|
|
strcat (abspath, filename);
|
|
abspath[sizehome + sizepath + 2] = '\0';
|
|
}
|
|
else
|
|
{
|
|
abspath = filename;
|
|
}
|
|
|
|
/* Checks if the file path can be opened. */
|
|
if (open(abspath, O_RDONLY) < 0)
|
|
{
|
|
e->type = NO_FILE;
|
|
e->msg = abspath;
|
|
return NULL;
|
|
}
|
|
|
|
file_t *f;
|
|
f = malloc(sizeof(file_t*));
|
|
f->name = (char*) abspath;
|
|
f->hash = NULL;
|
|
f->hash_str = NULL;
|
|
return f;
|
|
}
|
|
|
|
void
|
|
file_close(file_t *f)
|
|
{
|
|
free(f->name);
|
|
free(f->hash);
|
|
free(f->hash_str);
|
|
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 */
|
|
MD5(file_buffer, file_size, f->hash);
|
|
|
|
/* Removes fime_buffer and file_size */
|
|
munmap(file_buffer, file_size);
|
|
|
|
return f->hash;
|
|
}
|
|
|
|
char*
|
|
file_md5_str(file_t *f, exception_t *e)
|
|
{
|
|
static const char digits[] = "0123456789abcdef";
|
|
f->hash_str = malloc (MD5_DIGEST_LENGTH+1);
|
|
|
|
for (size_t i = 0; i < MD5_DIGEST_LENGTH; i+=2)
|
|
{
|
|
f->hash_str[i] += digits[f->hash[i] / MD5_DIGEST_LENGTH];
|
|
f->hash_str[i+1] += digits[f->hash[i+1] % MD5_DIGEST_LENGTH];
|
|
}
|
|
|
|
f->hash_str[MD5_DIGEST_LENGTH] = '\0';
|
|
return f->hash_str;
|
|
}
|