This repository has been archived on 2021-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
modetw/src/file_t.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;
}