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)
* `glib` (>= 2.50)
* `girara` (>= 0.3.7)
* `libmagic` from file(1): for mime-type detection
The following dependencies are optional:
* `sqlite3` (>= 3.6.23): splite3 database backend
* `libmagic` from file(1): for mime-type detection
* `libsynctex` from TeXLive (>= 1.19): SyncTeX 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')
gtk3 = dependency('gtk+-3.0', version: '>=3.22')
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'
gtk_mac_integration = dependency('gtk-mac-integration-gtk3')
@ -77,7 +78,6 @@ flags = cc.get_supported_arguments(flags)
additional_sources = []
sqlite = dependency('sqlite3', version: '>=3.6.23', required: get_option('sqlite'))
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'))
if sqlite.found()
@ -94,11 +94,6 @@ if synctex.found()
endif
endif
if magic.found()
build_dependencies += magic
defines += '-DWITH_MAGIC'
endif
if seccomp.found()
build_dependencies += seccomp
defines += '-DWITH_SECCOMP'

View file

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

View file

@ -3,45 +3,27 @@
#include "content-type.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 <girara/utils.h>
#include <glib.h>
#include <magic.h>
#include <stdio.h>
struct zathura_content_type_context_s
{
#ifdef WITH_MAGIC
struct zathura_content_type_context_s {
magic_t magic;
#else
void* magic;
#endif
};
zathura_content_type_context_t*
zathura_content_type_new(void)
{
zathura_content_type_context_t* context =
g_try_malloc0(sizeof(zathura_content_type_context_t));
zathura_content_type_context_t* context = g_try_malloc0(sizeof(zathura_content_type_context_t));
if (context == NULL) {
return NULL;
}
#ifdef WITH_MAGIC
/* creat magic cookie */
static const int flags =
MAGIC_ERROR |
MAGIC_MIME_TYPE |
MAGIC_SYMLINK |
MAGIC_NO_CHECK_APPTYPE |
MAGIC_NO_CHECK_CDF |
MAGIC_NO_CHECK_ELF |
MAGIC_NO_CHECK_ENCODING;
static const int flags = MAGIC_ERROR | 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);
if (magic == NULL) {
girara_debug("failed creating the magic cookie");
@ -56,32 +38,22 @@ zathura_content_type_new(void)
}
context->magic = magic;
#endif
return context;
}
void
zathura_content_type_free(zathura_content_type_context_t* context)
{
if (context == NULL) {
return;
}
#ifdef WITH_MAGIC
if (context->magic != NULL) {
if (context != NULL && context->magic != NULL) {
magic_close(context->magic);
}
#endif
g_free(context);
}
/** Read a most GT_MAX_READ bytes before falling back to file. */
static const size_t GT_MAX_READ = 1 << 16;
#ifdef WITH_MAGIC
static char*
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;
}
#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*
guess_type_glib(const char* path)
{
gboolean uncertain = FALSE;
char* content_type = g_content_type_guess(path, NULL, 0, &uncertain);
gboolean uncertain = FALSE;
char* content_type = g_content_type_guess(path, NULL, 0, &uncertain);
if (content_type == NULL) {
girara_debug("g_content_type failed\n");
} else {
@ -186,7 +108,7 @@ guess_type_glib(const char* path)
}
guchar* content = NULL;
size_t length = 0;
size_t length = 0;
while (uncertain == TRUE && length < GT_MAX_READ) {
g_free(content_type);
content_type = NULL;
@ -217,21 +139,21 @@ guess_type_glib(const char* path)
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);
}
char*
zathura_content_type_guess(zathura_content_type_context_t* context,
const char* path,
zathura_content_type_guess(zathura_content_type_context_t* context, const char* path,
const girara_list_t* supported_content_types)
{
/* try libmagic first */
char *content_type = guess_type_magic(context, path);
char* content_type = guess_type_magic(context, path);
if (content_type != NULL) {
if (supported_content_types == NULL ||
girara_list_find(supported_content_types, compare_content_types,
content_type) != NULL) {
girara_list_find(supported_content_types, compare_content_types, content_type) != NULL) {
return 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);
if (content_type != NULL) {
if (supported_content_types == NULL ||
girara_list_find(supported_content_types, compare_content_types,
content_type) != NULL) {
girara_list_find(supported_content_types, compare_content_types, content_type) != NULL) {
return content_type;
}
girara_debug("content type '%s' not supported, trying again", content_type);