#include #include #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, filepath_t FILEPATH, exception_t *e) { char *path = NULL; switch (FILEPATH) { case FILEPATH_ABSOLUTE: { realpath(filename, path); 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; } /* Checks if the file path can be opened. */ if (open(path, O_RDONLY) < 0) { e->type = NO_FILE; e->msg = path; return NULL; } file_t *f; f = malloc(sizeof(file_t)); f->name = path; f->hash_str = NULL; f->fp = FILEPATH; return f; } void file_close(file_t *f) { switch (f->fp) { case FILEPATH_ABSOLUTE: case FILEPATH_HOME: free(f->name); default: break; } if (f->hash_str != NULL) 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 */ if (MD5(file_buffer, file_size, f->hash) == NULL) { e->type = MD5SUM_GEN_FAIL; e->msg = "No 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 (2*MD5_DIGEST_LENGTH+1); size_t si = 0; for (size_t i = si; i < MD5_DIGEST_LENGTH; i++) { f->hash_str[si++] = digits[f->hash[i] / MD5_DIGEST_LENGTH]; f->hash_str[si++] = digits[f->hash[i] % MD5_DIGEST_LENGTH]; } f->hash_str[2*MD5_DIGEST_LENGTH] = '\0'; return f->hash_str; } 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; }