summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac33
-rw-r--r--src/Makefile.am6
-rw-r--r--src/fr-archive.c95
3 files changed, 102 insertions, 32 deletions
diff --git a/configure.ac b/configure.ac
index 68e1d47..8285bcc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -164,6 +164,38 @@ fi
dnl ******************************
+dnl ******************************
+
+AC_ARG_ENABLE([magic],
+ AS_HELP_STRING([--enable-magic], [use libmagic to detect file type]),,
+ [enable_magic=no])
+
+if test x"$enable_magic" = x"yes" ; then
+ save_LIBS="$LIBS"
+ LIBS="$LIBS -lmagic"
+ AC_MSG_CHECKING([whether libmagic works])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([
+#include <magic.h>
+int main () { magic_t m = magic_open(MAGIC_NONE); }
+])],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ AC_MSG_ERROR([libmagic is needed for magic])])
+ LIBS="$save_LIBS"
+
+ MAGIC_CFLAGS=
+ MAGIC_LIBS=-lmagic
+
+ AC_SUBST(MAGIC_CFLAGS)
+ AC_SUBST(MAGIC_LIBS)
+
+ AC_DEFINE(ENABLE_MAGIC, 1, [define to enable magic])
+fi
+
+AM_CONDITIONAL(ENABLE_MAGIC, test x"$enable_magic" != x"no")
+
+dnl ******************************
+
YELP_HELP_INIT
dnl ******************************
@@ -211,5 +243,6 @@ Configuration:
Caja support: ${enable_caja_actions}
PackageKit support: ${enable_packagekit}
Run in place ${enable_run_in_place}
+ Use libmagic: ${enable_magic}
JSON support: ${enable_json_glib}
"
diff --git a/src/Makefile.am b/src/Makefile.am
index cba14ad..ef11ec3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -189,7 +189,11 @@ fr-enum-types.c: typedefs.h fr-enum-types.h
engrampa_LDADD = \
$(top_builddir)/copy-n-paste/libeggsmclient.la \
$(FR_LIBS) \
- ${JSON_GLIB_LIBS}
+ ${JSON_GLIB_LIBS}
+
+if ENABLE_MAGIC
+engrampa_LDADD += $(MAGIC_LIBS)
+endif
EXTRA_DIST = fr-marshal.list
diff --git a/src/fr-archive.c b/src/fr-archive.c
index ab3e417..c2d1db3 100644
--- a/src/fr-archive.c
+++ b/src/fr-archive.c
@@ -41,6 +41,10 @@
#include "fr-process.h"
#include "main.h"
+#if ENABLE_MAGIC
+#include <magic.h>
+#endif
+
#ifndef NCARGS
#define NCARGS _POSIX_ARG_MAX
#endif
@@ -525,43 +529,72 @@ get_mime_type_from_content (GFile *file)
static const char *
get_mime_type_from_magic_numbers (GFile *file)
{
- static struct {
- const char *mime_type;
- const char *first_bytes;
- int offset;
- int len;
- } sniffer_data [] = {
- /* Magic numbers taken from magic/Magdir/archive from the
- * file-4.21 tarball. */
- { "application/x-7z-compressed", "7z\274\257\047\034", 0, 5 },
- { "application/x-ace", "**ACE**", 7, 7 },
- { "application/x-arj", "\x60\xea", 0, 2 },
- { "application/x-bzip2", "BZh", 0, 3 },
- { "application/x-gzip", "\037\213", 0, 2 },
- { "application/x-lzip", "LZIP", 0, 4 },
- { "application/x-lzop", "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 0, 9 },
- { "application/x-rar", "Rar!", 0, 4 },
- { "application/x-rzip", "RZIP", 0, 4 },
- { "application/x-xz", "\3757zXZ\000", 0, 6 },
- { "application/x-zoo", "\xdc\xa7\xc4\xfd", 20, 4 },
- { "application/zip", "PK\003\004", 0, 4 },
- { "application/zip", "PK00PK\003\004", 0, 8 },
- { "application/x-lrzip", "LRZI", 0, 4 },
- { NULL, NULL, 0 }
+#if ENABLE_MAGIC
+ static magic_t magic = NULL;
+
+ if (! magic) {
+ magic = magic_open (MAGIC_MIME_TYPE);
+ if (magic)
+ magic_load (magic, NULL);
+ else
+ g_warning ("unable to open magic database");
+ }
+
+ if (magic) {
+ const char * mime_type = NULL;
+ char * filepath = g_file_get_path (file);
+
+ if (filepath) {
+ mime_type = magic_file (magic, filepath);
+ g_free (filepath);
+ }
+
+ if (mime_type)
+ return mime_type;
+
+ g_warning ("unable to detect filetype from magic: %s",
+ magic_error (magic));
+ }
+#else
+ static const struct magic {
+ const unsigned int off;
+ const unsigned int len;
+ const char * const id;
+ const char * const mime_type;
+ } magic_ids [] = {
+ /* magic ids taken from magic/Magdir/archive from the file-4.21 tarball */
+ { 0, 6, "7z\274\257\047\034", "application/x-7z-compressed" },
+ { 7, 7, "**ACE**", "application/x-ace" },
+ { 0, 2, "\x60\xea", "application/x-arj" },
+ { 0, 3, "BZh", "application/x-bzip2" },
+ { 0, 2, "\037\213", "application/x-gzip" },
+ { 0, 4, "LZIP", "application/x-lzip" },
+ { 0, 9, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", "application/x-lzop", },
+ { 0, 4, "Rar!", "application/x-rar" },
+ { 0, 4, "RZIP", "application/x-rzip" },
+ { 0, 6, "\3757zXZ\000", "application/x-xz" },
+ { 20, 4, "\xdc\xa7\xc4\xfd", "application/x-zoo", },
+ { 0, 4, "PK\003\004", "application/zip" },
+ { 0, 8, "PK00PK\003\004", "application/zip" },
+ { 0, 4, "LRZI", "application/x-lrzip" },
};
+
char buffer[32];
int i;
- if (! g_load_file_in_buffer (file, buffer, 32, NULL))
+ if (! g_load_file_in_buffer (file, buffer, sizeof (buffer), NULL))
return NULL;
- for (i = 0; sniffer_data[i].mime_type != NULL; i++)
- if (memcmp (sniffer_data[i].first_bytes,
- buffer + sniffer_data[i].offset,
- sniffer_data[i].len) == 0)
- {
- return sniffer_data[i].mime_type;
- }
+ for (i = 0; i < G_N_ELEMENTS (magic_ids); i++) {
+ const struct magic * const magic = &magic_ids[i];
+
+ if (sizeof (buffer) < (magic->off + magic->len))
+ g_warning ("buffer underrun for mime type '%s' magic",
+ magic->mime_type);
+ else if (! memcmp (buffer + magic->off, magic->id, magic->len))
+ return magic->mime_type;
+ }
+#endif
return NULL;
}