diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 6 | ||||
| -rw-r--r-- | src/fr-archive.c | 95 | 
2 files changed, 69 insertions, 32 deletions
| 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;  } | 
