diff --git a/document.c b/document.c index 37a1db8..11c1f6d 100644 --- a/document.c +++ b/document.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "document.h" #include "utils.h" @@ -148,6 +149,48 @@ zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* return atleastone; } +static const gchar* +guess_type(const char* path) +{ + gboolean uncertain; + const gchar* content_type = g_content_type_guess(path, NULL, 0, &uncertain); + if (content_type == NULL) { + return NULL; + } + + FILE* f = fopen(path, "r"); + if (f == NULL) { + return NULL; + } + + const int fd = fileno(f); + static const size_t BLKSIZE = 4096; + guchar* content = NULL; + size_t length = 0u; + while (uncertain == TRUE) { + g_free((void*)content_type); + content_type = NULL; + + content = g_realloc(content, length + BLKSIZE); + const ssize_t r = read(fd, content + length, BLKSIZE); + if (r == -1) { + break; + } + + length += r; + content_type = g_content_type_guess(NULL, content, length, &uncertain); + } + + fclose(f); + if (uncertain == TRUE) { + g_free((void*)content_type); + content_type = NULL; + } + + g_free(content); + return content_type; +} + zathura_document_t* zathura_document_open(zathura_t* zathura, const char* path, const char* password) { @@ -160,33 +203,12 @@ zathura_document_open(zathura_t* zathura, const char* path, const char* password return NULL; } - gboolean uncertain; - const gchar* content_type = g_content_type_guess(path, NULL, 0, &uncertain); + const gchar* content_type = guess_type(path); if (content_type == NULL) { - girara_error("Could not determine file type"); + girara_error("Could not determine file type."); return NULL; } - if (uncertain == TRUE) { - g_free((void*)content_type); - content_type = NULL; - - gchar* contents = NULL; - gsize length = 0; - if (g_file_get_contents(path, &contents, &length, NULL) == FALSE) { - girara_error("Could not determine file type"); - return NULL; - } - - content_type = g_content_type_guess(NULL, (guchar*) contents, length, &uncertain); - g_free(contents); - if (content_type == NULL || uncertain == TRUE) { - g_free((void*)content_type); - girara_error("Could not determine file type"); - return NULL; - } - } - /* determine real path */ long path_max; #ifdef PATH_MAX