Make magic a required dependency

This commit is contained in:
Sebastian Ramacher 2022-05-08 15:43:16 +02:00
parent 2af36e27fc
commit 57f0d79e25
4 changed files with 22 additions and 111 deletions

View file

@ -12,11 +12,11 @@ The following dependencies are required:
* `gtk3` (>= 3.22) * `gtk3` (>= 3.22)
* `glib` (>= 2.50) * `glib` (>= 2.50)
* `girara` (>= 0.3.7) * `girara` (>= 0.3.7)
* `libmagic` from file(1): for mime-type detection
The following dependencies are optional: The following dependencies are optional:
* `sqlite3` (>= 3.6.23): splite3 database backend * `sqlite3` (>= 3.6.23): splite3 database backend
* `libmagic` from file(1): for mime-type detection
* `libsynctex` from TeXLive (>= 1.19): SyncTeX support * `libsynctex` from TeXLive (>= 1.19): SyncTeX support
* `libseccomp`: sandbox support * `libseccomp`: sandbox support

View file

@ -44,8 +44,9 @@ gthread = dependency('gthread-2.0', version: '>=2.50')
gmodule = dependency('gmodule-no-export-2.0', version: '>=2.50') gmodule = dependency('gmodule-no-export-2.0', version: '>=2.50')
gtk3 = dependency('gtk+-3.0', version: '>=3.22') gtk3 = dependency('gtk+-3.0', version: '>=3.22')
cairo = dependency('cairo') cairo = dependency('cairo')
magic = cc.find_library('magic', required: true)
build_dependencies = [libm, girara, glib, gio, gthread, gmodule, gtk3, cairo] build_dependencies = [libm, girara, glib, gio, gthread, gmodule, gtk3, cairo, magic]
if host_machine.system() == 'darwin' if host_machine.system() == 'darwin'
gtk_mac_integration = dependency('gtk-mac-integration-gtk3') gtk_mac_integration = dependency('gtk-mac-integration-gtk3')
@ -77,7 +78,6 @@ flags = cc.get_supported_arguments(flags)
additional_sources = [] additional_sources = []
sqlite = dependency('sqlite3', version: '>=3.6.23', required: get_option('sqlite')) sqlite = dependency('sqlite3', version: '>=3.6.23', required: get_option('sqlite'))
synctex = dependency('synctex', version: '>=1.19', required: get_option('synctex')) synctex = dependency('synctex', version: '>=1.19', required: get_option('synctex'))
magic = cc.find_library('magic', required: get_option('magic'))
seccomp = dependency('libseccomp', required: get_option('seccomp')) seccomp = dependency('libseccomp', required: get_option('seccomp'))
if sqlite.found() if sqlite.found()
@ -94,11 +94,6 @@ if synctex.found()
endif endif
endif endif
if magic.found()
build_dependencies += magic
defines += '-DWITH_MAGIC'
endif
if seccomp.found() if seccomp.found()
build_dependencies += seccomp build_dependencies += seccomp
defines += '-DWITH_SECCOMP' defines += '-DWITH_SECCOMP'

View file

@ -8,11 +8,6 @@ option('synctex',
value: 'auto', value: 'auto',
description: 'SyncTeX integration' description: 'SyncTeX integration'
) )
option('magic',
type: 'feature',
value: 'auto',
description: 'magic-based MIME type detection'
)
option('seccomp', option('seccomp',
type: 'feature', type: 'feature',
value: 'auto', value: 'auto',

View file

@ -3,45 +3,27 @@
#include "content-type.h" #include "content-type.h"
#include "macros.h" #include "macros.h"
#include <girara/utils.h>
#ifdef WITH_MAGIC
#include <magic.h>
#else
#include <sys/types.h>
#include <sys/wait.h>
#endif
#include <stdio.h>
#include <glib.h>
#include <gio/gio.h> #include <gio/gio.h>
#include <girara/utils.h>
#include <glib.h>
#include <magic.h>
#include <stdio.h>
struct zathura_content_type_context_s struct zathura_content_type_context_s {
{
#ifdef WITH_MAGIC
magic_t magic; magic_t magic;
#else
void* magic;
#endif
}; };
zathura_content_type_context_t* zathura_content_type_context_t*
zathura_content_type_new(void) zathura_content_type_new(void)
{ {
zathura_content_type_context_t* context = zathura_content_type_context_t* context = g_try_malloc0(sizeof(zathura_content_type_context_t));
g_try_malloc0(sizeof(zathura_content_type_context_t));
if (context == NULL) { if (context == NULL) {
return NULL; return NULL;
} }
#ifdef WITH_MAGIC
/* creat magic cookie */ /* creat magic cookie */
static const int flags = static const int flags = MAGIC_ERROR | MAGIC_MIME_TYPE | MAGIC_SYMLINK | MAGIC_NO_CHECK_APPTYPE | MAGIC_NO_CHECK_CDF |
MAGIC_ERROR | MAGIC_NO_CHECK_ELF | MAGIC_NO_CHECK_ENCODING;
MAGIC_MIME_TYPE |
MAGIC_SYMLINK |
MAGIC_NO_CHECK_APPTYPE |
MAGIC_NO_CHECK_CDF |
MAGIC_NO_CHECK_ELF |
MAGIC_NO_CHECK_ENCODING;
magic_t magic = magic_open(flags); magic_t magic = magic_open(flags);
if (magic == NULL) { if (magic == NULL) {
girara_debug("failed creating the magic cookie"); girara_debug("failed creating the magic cookie");
@ -56,32 +38,22 @@ zathura_content_type_new(void)
} }
context->magic = magic; context->magic = magic;
#endif
return context; return context;
} }
void void
zathura_content_type_free(zathura_content_type_context_t* context) zathura_content_type_free(zathura_content_type_context_t* context)
{ {
if (context == NULL) { if (context != NULL && context->magic != NULL) {
return;
}
#ifdef WITH_MAGIC
if (context->magic != NULL) {
magic_close(context->magic); magic_close(context->magic);
} }
#endif
g_free(context); g_free(context);
} }
/** Read a most GT_MAX_READ bytes before falling back to file. */ /** Read a most GT_MAX_READ bytes before falling back to file. */
static const size_t GT_MAX_READ = 1 << 16; static const size_t GT_MAX_READ = 1 << 16;
#ifdef WITH_MAGIC
static char* static char*
guess_type_magic(zathura_content_type_context_t* context, const char* path) guess_type_magic(zathura_content_type_context_t* context, const char* path)
{ {
@ -114,62 +86,12 @@ guess_type_file(const char* UNUSED(path))
{ {
return NULL; return NULL;
} }
#else
static char*
guess_type_magic(zathura_content_type_context_t* UNUSED(context),
const char* UNUSED(path))
{
return NULL;
}
static char*
guess_type_file(const char* path)
{
/* g_spawn_async expects char** */
static char cmd_file[] = "file";
static char opt_b[] = "-b";
static char opt_mime_type[] = "--mime-type";
char* argv[] = { cmd_file, opt_b, opt_mime_type, g_strdup(path), NULL };
GError* error = NULL;
char* out = NULL;
int ret = 0;
const bool r = g_spawn_sync(NULL, argv, NULL,
G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
NULL, NULL, &out, NULL, &ret, &error);
g_free(argv[3]);
if (r == false) {
girara_warning("failed to execute command: %s", error->message);
g_error_free(error);
g_free(out);
return NULL;
}
if (g_spawn_check_exit_status(ret, &error) == false) {
girara_warning("file failed: %s", error->message);
g_error_free(error);
g_free(out);
return NULL;
}
g_strdelimit(out, "\n\r", '\0');
girara_debug("file detected filetype: %s", out);
char* content_type = g_content_type_from_mime_type(out);
if (content_type == NULL) {
girara_warning("failed to convert mime type to content type: %s", out);
return out;
}
g_free(out);
return content_type;
}
#endif
static char* static char*
guess_type_glib(const char* path) guess_type_glib(const char* path)
{ {
gboolean uncertain = FALSE; gboolean uncertain = FALSE;
char* content_type = g_content_type_guess(path, NULL, 0, &uncertain); char* content_type = g_content_type_guess(path, NULL, 0, &uncertain);
if (content_type == NULL) { if (content_type == NULL) {
girara_debug("g_content_type failed\n"); girara_debug("g_content_type failed\n");
} else { } else {
@ -186,7 +108,7 @@ guess_type_glib(const char* path)
} }
guchar* content = NULL; guchar* content = NULL;
size_t length = 0; size_t length = 0;
while (uncertain == TRUE && length < GT_MAX_READ) { while (uncertain == TRUE && length < GT_MAX_READ) {
g_free(content_type); g_free(content_type);
content_type = NULL; content_type = NULL;
@ -217,21 +139,21 @@ guess_type_glib(const char* path)
return NULL; return NULL;
} }
static int compare_content_types(const void* lhs, const void* rhs) { static int
compare_content_types(const void* lhs, const void* rhs)
{
return g_strcmp0(lhs, rhs); return g_strcmp0(lhs, rhs);
} }
char* char*
zathura_content_type_guess(zathura_content_type_context_t* context, zathura_content_type_guess(zathura_content_type_context_t* context, const char* path,
const char* path,
const girara_list_t* supported_content_types) const girara_list_t* supported_content_types)
{ {
/* try libmagic first */ /* try libmagic first */
char *content_type = guess_type_magic(context, path); char* content_type = guess_type_magic(context, path);
if (content_type != NULL) { if (content_type != NULL) {
if (supported_content_types == NULL || if (supported_content_types == NULL ||
girara_list_find(supported_content_types, compare_content_types, girara_list_find(supported_content_types, compare_content_types, content_type) != NULL) {
content_type) != NULL) {
return content_type; return content_type;
} }
girara_debug("content type '%s' not supported, trying again", content_type); girara_debug("content type '%s' not supported, trying again", content_type);
@ -241,8 +163,7 @@ zathura_content_type_guess(zathura_content_type_context_t* context,
content_type = guess_type_glib(path); content_type = guess_type_glib(path);
if (content_type != NULL) { if (content_type != NULL) {
if (supported_content_types == NULL || if (supported_content_types == NULL ||
girara_list_find(supported_content_types, compare_content_types, girara_list_find(supported_content_types, compare_content_types, content_type) != NULL) {
content_type) != NULL) {
return content_type; return content_type;
} }
girara_debug("content type '%s' not supported, trying again", content_type); girara_debug("content type '%s' not supported, trying again", content_type);