read file blockwise to determine filetype

This commit is contained in:
Sebastian Ramacher 2011-10-23 19:26:06 +02:00
parent 49b682e0a8
commit 7ca688a964

View file

@ -15,6 +15,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <glib.h>
#include "document.h" #include "document.h"
#include "utils.h" #include "utils.h"
@ -148,6 +149,48 @@ zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t*
return atleastone; 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_t*
zathura_document_open(zathura_t* zathura, const char* path, const char* password) 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; return NULL;
} }
gboolean uncertain; const gchar* content_type = guess_type(path);
const gchar* content_type = g_content_type_guess(path, NULL, 0, &uncertain);
if (content_type == NULL) { if (content_type == NULL) {
girara_error("Could not determine file type"); girara_error("Could not determine file type.");
return NULL; 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 */ /* determine real path */
long path_max; long path_max;
#ifdef PATH_MAX #ifdef PATH_MAX