#include #include #include #include /* md5sum */ #include #include #include #include #include #include #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; }