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

131 lines
2.6 KiB
C
Raw Permalink Normal View History

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*
file_init(const char *filename, filepath_t FILEPATH, exception_t *e)
2021-05-15 19:18:42 +02:00
{
2021-06-03 00:33:26 +02:00
char *path = NULL;
switch (FILEPATH) {
case FILEPATH_ABSOLUTE: {
2021-06-03 00:33:26 +02:00
realpath(filename, path);
2021-06-12 11:02:56 +02:00
break;
}
case FILEPATH_HOME: {
char* home = getenv("HOME");
size_t pathlen = strlen(home) + strlen(filename);
path = malloc(pathlen + 1);
strcpy(home, path);
strcat(path, filename);
path[pathlen] = '\0';
}
case FILEPATH_RELATIVE: path = (char*) filename; break;
}
2021-05-15 19:18:42 +02:00
/* Checks if the file path can be opened. */
if (open(path, O_RDONLY) < 0)
2021-05-15 19:18:42 +02:00
{
e->type = NO_FILE;
e->msg = path;
2021-05-15 19:18:42 +02:00
return NULL;
}
file_t *f;
f = malloc(sizeof(file_t));
2021-06-03 00:33:26 +02:00
f->name = path;
2021-05-15 19:18:42 +02:00
f->hash_str = NULL;
2021-06-03 00:33:26 +02:00
f->fp = FILEPATH;
2021-05-15 19:18:42 +02:00
return f;
}
void
file_close(file_t *f)
{
2021-06-12 11:02:56 +02:00
switch (f->fp) {
case FILEPATH_ABSOLUTE:
case FILEPATH_HOME: free(f->name);
default: break;
}
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 */
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-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";
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
{
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
}
f->hash_str[2*MD5_DIGEST_LENGTH] = '\0';
2021-05-15 19:18:42 +02:00
return f->hash_str;
}
2021-06-03 00:33:26 +02:00
char*
file_abs(const file_t *f) {
char *path = NULL;
switch (f->fp) {
case FILEPATH_ABSOLUTE: return f->name;
case FILEPATH_RELATIVE: {
realpath(f->name, path);
break;
}
}
return path;
}