diff --git a/ChangeLog b/ChangeLog
index 848765a347fbea7c99db53681abba4d2ee44e4cc..4e06c4e80c5d1e875cadb19ec17f8953821bf2b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-03-07	Benedikt Meurer <benny@xfce.org>
+
+	* thunar-vfs/thunar-vfs-mime-legacy.c: Implement magic handling for
+	  the legacy backend (shared-mime-info <= 0.16). Bug #1106.
+
 2006-03-07	Benedikt Meurer <benny@xfce.org>
 
 	* thunar-vfs/thunar-vfs-xfer.c: Automatically give write permissions to
diff --git a/thunar-vfs/thunar-vfs-mime-legacy.c b/thunar-vfs/thunar-vfs-mime-legacy.c
index d35436a4cf6a9f3c9ff72f1ecc9ef24962a51af0..f039aa96ee503ae99f75880e6517714f4f61c9b7 100644
--- a/thunar-vfs/thunar-vfs-mime-legacy.c
+++ b/thunar-vfs/thunar-vfs-mime-legacy.c
@@ -1,6 +1,6 @@
 /* $Id$ */
 /*-
- * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -25,13 +25,22 @@
 #include <config.h>
 #endif
 
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
 #ifdef HAVE_FNMATCH_H
 #include <fnmatch.h>
 #endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
 #include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
@@ -41,44 +50,57 @@
 
 
 
-#define THUNAR_VFS_MIME_LEGACY_GLOB(obj)   ((ThunarVfsMimeLegacyGlob *) (obj))
-#define THUNAR_VFS_MIME_LEGACY_SUFFIX(obj) ((ThunarVfsMimeLegacySuffix *) (obj))
-
-
-
-typedef struct _ThunarVfsMimeLegacyGlob   ThunarVfsMimeLegacyGlob;
-typedef struct _ThunarVfsMimeLegacySuffix ThunarVfsMimeLegacySuffix;
-
-
-
-static void         thunar_vfs_mime_legacy_class_init             (ThunarVfsMimeLegacyClass *klass);
-static void         thunar_vfs_mime_legacy_init                   (ThunarVfsMimeLegacy      *legacy);
-static void         thunar_vfs_mime_legacy_finalize               (GObject                  *object);
-static const gchar *thunar_vfs_mime_legacy_lookup_data            (ThunarVfsMimeProvider    *provider,
-                                                                   gconstpointer             data,
-                                                                   gsize                     length,
-                                                                   gint                     *priority);
-static const gchar *thunar_vfs_mime_legacy_lookup_literal         (ThunarVfsMimeProvider    *provider,
-                                                                   const gchar              *filename);
-static const gchar *thunar_vfs_mime_legacy_lookup_suffix          (ThunarVfsMimeProvider    *provider,
-                                                                   const gchar              *suffix,
-                                                                   gboolean                  ignore_case);
-static const gchar *thunar_vfs_mime_legacy_lookup_glob            (ThunarVfsMimeProvider    *provider,
-                                                                   const gchar              *filename);
-static const gchar *thunar_vfs_mime_legacy_lookup_alias           (ThunarVfsMimeProvider    *provider,
-                                                                   const gchar              *alias);
-static guint        thunar_vfs_mime_legacy_lookup_parents         (ThunarVfsMimeProvider    *provider,
-                                                                   const gchar              *mime_type,
-                                                                   gchar                   **parents,
-                                                                   guint                     max_parents);
-static GList       *thunar_vfs_mime_legacy_get_stop_characters    (ThunarVfsMimeProvider    *provider);
-static gsize        thunar_vfs_mime_legacy_get_max_buffer_extents (ThunarVfsMimeProvider    *provider);
-static void         thunar_vfs_mime_legacy_parse_aliases          (ThunarVfsMimeLegacy      *legacy,
-                                                                   const gchar              *directory);
-static gboolean     thunar_vfs_mime_legacy_parse_globs            (ThunarVfsMimeLegacy      *legacy,
-                                                                   const gchar              *directory);
-static void         thunar_vfs_mime_legacy_parse_subclasses       (ThunarVfsMimeLegacy      *legacy,
-                                                                   const gchar              *directory);
+#define THUNAR_VFS_MIME_LEGACY_GLOB(obj)      ((ThunarVfsMimeLegacyGlob *) (obj))
+#define THUNAR_VFS_MIME_LEGACY_SUFFIX(obj)    ((ThunarVfsMimeLegacySuffix *) (obj))
+#define THUNAR_VFS_MIME_LEGACY_MATCH(obj)     ((ThunarVfsMimeLegacyMatch *) (obj))
+#define THUNAR_VFS_MIME_LEGACY_MATCHLET(obj)  ((ThunarVfsMimeLegacyMatchlet *) (obj))
+
+
+
+typedef struct _ThunarVfsMimeLegacyGlob     ThunarVfsMimeLegacyGlob;
+typedef struct _ThunarVfsMimeLegacySuffix   ThunarVfsMimeLegacySuffix;
+typedef struct _ThunarVfsMimeLegacyMatch    ThunarVfsMimeLegacyMatch;
+typedef struct _ThunarVfsMimeLegacyMatchlet ThunarVfsMimeLegacyMatchlet;
+typedef enum   _ThunarVfsMimeLegacyMagic    ThunarVfsMimeLegacyMagic;
+
+
+
+static void                     thunar_vfs_mime_legacy_class_init             (ThunarVfsMimeLegacyClass *klass);
+static void                     thunar_vfs_mime_legacy_init                   (ThunarVfsMimeLegacy      *legacy);
+static void                     thunar_vfs_mime_legacy_finalize               (GObject                  *object);
+static const gchar             *thunar_vfs_mime_legacy_lookup_data            (ThunarVfsMimeProvider    *provider,
+                                                                               gconstpointer             data,
+                                                                               gsize                     length,
+                                                                               gint                     *priority);
+static const gchar             *thunar_vfs_mime_legacy_lookup_literal         (ThunarVfsMimeProvider    *provider,
+                                                                               const gchar              *filename);
+static const gchar             *thunar_vfs_mime_legacy_lookup_suffix          (ThunarVfsMimeProvider    *provider,
+                                                                               const gchar              *suffix,
+                                                                               gboolean                  ignore_case);
+static const gchar             *thunar_vfs_mime_legacy_lookup_glob            (ThunarVfsMimeProvider    *provider,
+                                                                               const gchar              *filename);
+static const gchar             *thunar_vfs_mime_legacy_lookup_alias           (ThunarVfsMimeProvider    *provider,
+                                                                               const gchar              *alias);
+static guint                    thunar_vfs_mime_legacy_lookup_parents         (ThunarVfsMimeProvider    *provider,
+                                                                               const gchar              *mime_type,
+                                                                               gchar                   **parents,
+                                                                               guint                     max_parents);
+static GList                   *thunar_vfs_mime_legacy_get_stop_characters    (ThunarVfsMimeProvider    *provider);
+static gsize                    thunar_vfs_mime_legacy_get_max_buffer_extents (ThunarVfsMimeProvider    *provider);
+static void                     thunar_vfs_mime_legacy_parse_aliases          (ThunarVfsMimeLegacy      *legacy,
+                                                                               const gchar              *directory);
+static gboolean                 thunar_vfs_mime_legacy_parse_globs            (ThunarVfsMimeLegacy      *legacy,
+                                                                               const gchar              *directory);
+static void                     thunar_vfs_mime_legacy_parse_subclasses       (ThunarVfsMimeLegacy      *legacy,
+                                                                               const gchar              *directory);
+static void                     thunar_vfs_mime_legacy_parse_magic            (ThunarVfsMimeLegacy      *legacy,
+                                                                               const gchar              *directory);
+static ThunarVfsMimeLegacyMagic thunar_vfs_mime_legacy_parse_magic_header     (ThunarVfsMimeLegacy      *legacy,
+                                                                               ThunarVfsMimeLegacyMatch *match,
+                                                                               FILE                     *fp);
+static ThunarVfsMimeLegacyMagic thunar_vfs_mime_legacy_parse_magic_line       (ThunarVfsMimeLegacy      *legacy,
+                                                                               ThunarVfsMimeLegacyMatch *match,
+                                                                               FILE                     *fp);
 
 
 
@@ -94,6 +116,8 @@ struct _ThunarVfsMimeLegacy
   GStringChunk              *string_chunk;
   GMemChunk                 *suffix_chunk;
   GMemChunk                 *glob_chunk;
+  GMemChunk                 *match_chunk;
+  GMemChunk                 *matchlet_chunk;
 
   GHashTable                *literals;
   ThunarVfsMimeLegacySuffix *suffixes;
@@ -101,6 +125,9 @@ struct _ThunarVfsMimeLegacy
 
   GHashTable                *aliases;
   GHashTable                *parents;
+
+  GList                     *matches;
+  gsize                      max_buffer_extents;
 };
 
 struct _ThunarVfsMimeLegacyGlob
@@ -117,6 +144,32 @@ struct _ThunarVfsMimeLegacySuffix
   gunichar                   character;
 };
 
+struct _ThunarVfsMimeLegacyMatch
+{
+  const gchar *mime_type;
+  gint         priority;
+  GList       *matchlets;
+};
+
+struct _ThunarVfsMimeLegacyMatchlet
+{
+  gint    indent;
+  gint    offset;
+  guint   value_length;
+  guchar *value;
+  guchar *mask;
+  guint   range_length;
+  guint   word_size;
+};
+
+enum _ThunarVfsMimeLegacyMagic
+{
+  THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION,
+  THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC,
+  THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR,
+  THUNAR_VFS_MIME_LEGACY_MAGIC_EOF,
+};
+
 
 
 static GObjectClass *thunar_vfs_mime_legacy_parent_class;
@@ -183,6 +236,8 @@ thunar_vfs_mime_legacy_init (ThunarVfsMimeLegacy *legacy)
   legacy->string_chunk = g_string_chunk_new (1024);
   legacy->glob_chunk = g_mem_chunk_create (ThunarVfsMimeLegacyGlob, 32, G_ALLOC_ONLY);
   legacy->suffix_chunk = g_mem_chunk_create (ThunarVfsMimeLegacySuffix, 128, G_ALLOC_ONLY);
+  legacy->match_chunk = g_mem_chunk_create (ThunarVfsMimeLegacyMatch, 16, G_ALLOC_ONLY);
+  legacy->matchlet_chunk = g_mem_chunk_create (ThunarVfsMimeLegacyMatchlet, 32, G_ALLOC_ONLY);
 
   legacy->literals = g_hash_table_new (g_str_hash, g_str_equal);
 
@@ -196,6 +251,12 @@ static void
 thunar_vfs_mime_legacy_finalize (GObject *object)
 {
   ThunarVfsMimeLegacy *legacy = THUNAR_VFS_MIME_LEGACY (object);
+  GList               *lp;
+
+  /* free match and matchlet lists */
+  for (lp = legacy->matches; lp != NULL; lp = lp->next)
+    g_list_free (THUNAR_VFS_MIME_LEGACY_MATCH (lp->data)->matchlets);
+  g_list_free (legacy->matches);
 
   /* free parents hash table */
   g_hash_table_destroy (legacy->parents);
@@ -213,18 +274,103 @@ thunar_vfs_mime_legacy_finalize (GObject *object)
   g_string_chunk_free (legacy->string_chunk);
   g_mem_chunk_destroy (legacy->suffix_chunk);
   g_mem_chunk_destroy (legacy->glob_chunk);
+  g_mem_chunk_destroy (legacy->match_chunk);
+  g_mem_chunk_destroy (legacy->matchlet_chunk);
 
   (*G_OBJECT_CLASS (thunar_vfs_mime_legacy_parent_class)->finalize) (object);
 }
 
 
 
+static gboolean
+tvml_matchlet_compare_to_data (ThunarVfsMimeLegacyMatchlet *matchlet,
+                               gconstpointer                data,
+                               gsize                        length)
+{
+  gboolean valid_matchlet;
+  gint     i, j;
+
+  for (i = matchlet->offset; i < matchlet->offset + matchlet->range_length; i++)
+    {
+      valid_matchlet = TRUE;
+
+      if (i + matchlet->value_length > length)
+        return FALSE;
+
+      if (matchlet->mask)
+        {
+          for (j = 0; j < matchlet->value_length; j++)
+            if ((matchlet->value[j] & matchlet->mask[j]) != ((((const guchar *) data)[j + i]) & matchlet->mask[j]))
+              {
+                valid_matchlet = FALSE;
+                break;
+              }
+        }
+      else
+        {
+          for (j = 0; j <  matchlet->value_length; j++)
+            if (matchlet->value[j] != ((const guchar *) data)[j + i])
+              {
+                valid_matchlet = FALSE;
+                break;
+              }
+        }
+
+      if (valid_matchlet)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+
+static gboolean
+tvml_matchlet_compare_level (GList         *matchlet_list,
+                             gconstpointer  data,
+                             gsize          length,
+                             gint           indent)
+{
+  while (matchlet_list != NULL && THUNAR_VFS_MIME_LEGACY_MATCHLET (matchlet_list->data)->indent == indent)
+    {
+      if (tvml_matchlet_compare_to_data (matchlet_list->data, data, length))
+        {
+          if (matchlet_list->next == NULL || THUNAR_VFS_MIME_LEGACY_MATCHLET (matchlet_list->next->data)->indent <= indent)
+            return TRUE;
+
+          if (tvml_matchlet_compare_level (matchlet_list->next, data, length, indent + 1))
+            return TRUE;
+        }
+
+      do
+        {
+          matchlet_list = matchlet_list->next;
+        }
+      while (matchlet_list != NULL && THUNAR_VFS_MIME_LEGACY_MATCHLET (matchlet_list->data)->indent > indent);
+    }
+
+  return FALSE;
+}
+
+
+
 static const gchar*
 thunar_vfs_mime_legacy_lookup_data (ThunarVfsMimeProvider *provider,
                                     gconstpointer          data,
                                     gsize                  length,
                                     gint                  *priority)
 {
+  ThunarVfsMimeLegacy *legacy = THUNAR_VFS_MIME_LEGACY (provider);
+  GList               *lp;
+
+  for (lp = legacy->matches; lp != NULL; lp = lp->next)
+    if (tvml_matchlet_compare_level (THUNAR_VFS_MIME_LEGACY_MATCH (lp->data)->matchlets, data, length, 0))
+      {
+        if (G_LIKELY (priority != NULL))
+          *priority = THUNAR_VFS_MIME_LEGACY_MATCH (lp->data)->priority;
+        return THUNAR_VFS_MIME_LEGACY_MATCH (lp->data)->mime_type;
+      }
+
   return NULL;
 }
 
@@ -404,7 +550,7 @@ thunar_vfs_mime_legacy_get_stop_characters (ThunarVfsMimeProvider *provider)
 static gsize
 thunar_vfs_mime_legacy_get_max_buffer_extents (ThunarVfsMimeProvider *provider)
 {
-  return 0;
+  return THUNAR_VFS_MIME_LEGACY (provider)->max_buffer_extents;
 }
 
 
@@ -602,6 +748,402 @@ thunar_vfs_mime_legacy_parse_subclasses (ThunarVfsMimeLegacy *legacy,
 
 
 
+static gint
+thunar_vfs_mime_legacy_match_compare (gconstpointer a,
+                                      gconstpointer b)
+{
+  return (-1) * (THUNAR_VFS_MIME_LEGACY_MATCH (a)->priority - THUNAR_VFS_MIME_LEGACY_MATCH (b)->priority);
+}
+
+
+
+static void
+thunar_vfs_mime_legacy_parse_magic (ThunarVfsMimeLegacy *legacy,
+                                    const gchar         *directory)
+{
+  ThunarVfsMimeLegacyMatch *match = NULL;
+  ThunarVfsMimeLegacyMagic  state;
+  gchar                     header[12];
+  gchar                    *path;
+  GList                    *lp;
+  FILE                     *fp;
+  gint                      c;
+  gint                      n;
+
+  /* try to open the "magic" file */
+  path = g_build_filename (directory, "magic", NULL);
+  fp = fopen (path, "r");
+  g_free (path);
+
+  /* check if we succeed */
+  if (G_UNLIKELY (fp == NULL))
+    return;
+
+  /* check the header */
+  if (fread (header, 1, 12, fp) == 12 && memcmp ("MIME-Magic\0\n", header, 12) == 0)
+    {
+      /* parse the file */
+      for (state = THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION; state != THUNAR_VFS_MIME_LEGACY_MAGIC_EOF; )
+        {
+          switch (state)
+            {
+            case THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION:
+              match = g_chunk_new0 (ThunarVfsMimeLegacyMatch, legacy->match_chunk);
+              state = thunar_vfs_mime_legacy_parse_magic_header (legacy, match, fp);
+              if (state == THUNAR_VFS_MIME_LEGACY_MAGIC_EOF || state == THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR)
+                match = NULL;
+              break;
+
+            case THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC:
+              state = thunar_vfs_mime_legacy_parse_magic_line (legacy, match, fp);
+              if ((state == THUNAR_VFS_MIME_LEGACY_MAGIC_EOF && match->mime_type != NULL)
+                  || (state == THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION))
+                {
+                  /* determine new max buffer extents */
+                  for (lp = match->matchlets; lp != NULL; lp = lp->next)
+                    {
+                      /* calculate matchlet extent */
+                      n = THUNAR_VFS_MIME_LEGACY_MATCHLET (lp->data)->value_length
+                        + THUNAR_VFS_MIME_LEGACY_MATCHLET (lp->data)->range_length
+                        + THUNAR_VFS_MIME_LEGACY_MATCHLET (lp->data)->offset;
+                    
+                      /* check if new max */
+                      if (n > legacy->max_buffer_extents)
+                        legacy->max_buffer_extents = n;
+                    }
+
+                  /* add to internal match list */
+                  legacy->matches = g_list_insert_sorted (legacy->matches, match, thunar_vfs_mime_legacy_match_compare);
+                }
+              else if (state == THUNAR_VFS_MIME_LEGACY_MAGIC_EOF || state == THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR)
+                match = NULL;
+              break;
+
+            case THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR:
+              for (;;)
+                {
+                  c = getc_unlocked (fp);
+                  if (c == EOF)
+                    {
+                      state = THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+                      break;
+                    }
+                  else if (c == '\n')
+                    {
+                      state = THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION;
+                      break;
+                    }
+                }
+              break;
+
+            default:
+              /* should never be reached */
+              g_assert_not_reached ();
+            }
+        }
+     }
+
+  /* close the file */
+  fclose (fp);
+}
+
+
+
+/* Reads in a hunk of data until a newline character or a '\000' is hit.  The
+ * returned string is null terminated, and doesn't include the newline.
+ */
+static guchar*
+tvml_read_to_newline (FILE     *fp,
+                      gboolean *eof)
+{
+  guchar *retval;
+  gint    len = 128;
+  gint    pos = 0;
+  gint    c;
+
+  retval = g_malloc (len);
+  *eof = FALSE;
+
+  for (;;)
+    {
+      c = getc_unlocked (fp);
+      if (c == EOF)
+        {
+          *eof = TRUE;
+          break;
+        }
+      else if (c == '\n' || c == '\0')
+        break;
+
+      retval[pos++] = (guchar) c;
+      if (pos % 128 == 127)
+        {
+          len = len + 128;
+          retval = g_realloc (retval, len);
+        }
+    }
+
+  retval[pos] = '\0';
+  return retval;
+}
+
+
+
+/* Returns the number read from the file, or -1 if no number could be read.
+ */
+static glong
+tvml_read_a_number (FILE     *fp,
+                    gboolean *eof)
+{
+  gchar number_string[64];
+  glong retval = -1;
+  gint  pos = 0;
+  gint  c;
+
+  *eof = FALSE;
+
+  for (;;)
+    {
+      c = getc_unlocked (fp);
+      if (c == EOF)
+        {
+          *eof = TRUE;
+          break;
+        }
+      else if (!g_ascii_isdigit (c))
+        {
+          ungetc (c, fp);
+          break;
+        }
+
+      number_string[pos] = (gchar) c;
+      pos++;
+      if (pos == sizeof (number_string) - 1)
+        break;
+    }
+
+  if (G_LIKELY (pos > 0))
+    {
+      number_string[pos] = '\0';
+      errno = 0;
+      retval = strtol (number_string, NULL, 10);
+
+      if ((retval < INT_MIN) || (retval > INT_MAX) || (errno != 0))
+        return -1;
+    }
+
+  return retval;
+}
+
+
+
+static ThunarVfsMimeLegacyMagic
+thunar_vfs_mime_legacy_parse_magic_header (ThunarVfsMimeLegacy      *legacy,
+                                           ThunarVfsMimeLegacyMatch *match,
+                                           FILE                     *fp)
+{
+  /* Headers are of the format:
+   * [<priority>:<mime-type>]
+   */
+
+  gboolean eof = FALSE;
+  gchar   *buffer;
+  gchar   *bp;
+  gint     c;
+
+  c = getc_unlocked (fp);
+  if (c == EOF)
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+  else if (c != '[')
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+
+  match->priority = tvml_read_a_number (fp, &eof);
+  if (G_UNLIKELY (eof))
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+  else if (match->priority == -1)
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+
+  c = getc_unlocked (fp);
+  if (c == EOF)
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+  else if (c != ':')
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+
+  buffer = (gchar *) tvml_read_to_newline (fp, &eof);
+  if (G_UNLIKELY (eof))
+    {
+      g_free (buffer);
+      return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+    }
+
+  for (bp = buffer; *bp != ']' && *bp != '\0' && *bp != '\n'; ++bp)
+    ;
+  if (*bp != ']')
+    {
+      g_free (buffer);
+      return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+    }
+  *bp = '\0';
+
+  match->mime_type = g_string_chunk_insert_const (legacy->string_chunk, buffer);
+  g_free (buffer);
+
+  return THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC;
+}
+
+
+
+static ThunarVfsMimeLegacyMagic
+thunar_vfs_mime_legacy_parse_magic_line (ThunarVfsMimeLegacy      *legacy,
+                                         ThunarVfsMimeLegacyMatch *match,
+                                         FILE                     *fp)
+{
+  /* Lines are of the format:
+   * [ indent ] ">" start-offset "=" value
+   * [ "&" mask ] [ "~" word-size ] [ "+" range-length ] "\n"
+   */
+
+  ThunarVfsMimeLegacyMatchlet *matchlet;
+  gboolean                     eof = FALSE;
+  gchar                       *buffer;
+  gint                         bytes_read;
+  gint                         indent = 0;
+  gint                         c, i;
+
+  /* sniff the buffer to make sure it's a valid line */
+  c = getc_unlocked (fp);
+  if (c == EOF)
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+  else if (c == '[')
+    {
+      ungetc (c, fp);
+      return THUNAR_VFS_MIME_LEGACY_MAGIC_SECTION;
+    }
+  else if (c == '\n')
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC;
+
+  /* At this point, it must be a digit or a '>' */
+  if (g_ascii_isdigit (c))
+    {
+      ungetc (c, fp);
+      indent = tvml_read_a_number (fp, &eof);
+      if (G_UNLIKELY (eof))
+        return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+      else if (G_UNLIKELY (indent == -1))
+        return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+      c = getc_unlocked (fp);
+      if (c == EOF)
+        return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+    }
+
+  if (c != '>')
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+
+  matchlet = g_chunk_new0 (ThunarVfsMimeLegacyMatchlet, legacy->matchlet_chunk);
+  matchlet->indent = indent;
+  matchlet->range_length = 1;
+  matchlet->word_size = 1;
+  matchlet->offset = tvml_read_a_number (fp, &eof);
+
+  if (G_UNLIKELY (eof))
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+  else if (matchlet->offset == -1)
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+
+  c = getc_unlocked (fp);
+  if (c == EOF)
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+  else if (c != '=')
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+
+  /* Next two bytes determine how long the value is */
+  c = getc_unlocked (fp);
+  if (c == EOF)
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+  matchlet->value_length = (c & 0xFF) << 8;
+
+  c = getc_unlocked (fp);
+  if (c == EOF)
+    return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+  matchlet->value_length += (c & 0xFF);
+
+  buffer = g_alloca (matchlet->value_length);
+  bytes_read = fread (buffer, 1, matchlet->value_length, fp);
+  if (bytes_read != matchlet->value_length)
+    return feof (fp) ? THUNAR_VFS_MIME_LEGACY_MAGIC_EOF : THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+  matchlet->value = g_string_chunk_insert_len (legacy->string_chunk, buffer, matchlet->value_length);
+
+  c = getc_unlocked (fp);
+  if (c == '&')
+    {
+      /* reuse previously allocated buffer, as it's also value_length size */
+      bytes_read = fread (buffer, 1, matchlet->value_length, fp);
+      if (bytes_read != matchlet->value_length)
+        return feof (fp) ? THUNAR_VFS_MIME_LEGACY_MAGIC_EOF : THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+
+      matchlet->mask = g_string_chunk_insert_len (legacy->string_chunk, buffer, matchlet->value_length);
+
+      c = getc_unlocked (fp);
+    }
+
+  if (c == '~')
+    {
+      matchlet->word_size = tvml_read_a_number (fp, &eof);
+      if (G_UNLIKELY (eof))
+        return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+      if (matchlet->word_size != 0 && matchlet->word_size != 1 && matchlet->word_size != 2 && matchlet->word_size != 4)
+        return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+      c = getc_unlocked (fp);
+    }
+
+  if (c == '+')
+    {
+      matchlet->range_length = tvml_read_a_number (fp, &eof);
+      if (G_UNLIKELY (eof))
+        return THUNAR_VFS_MIME_LEGACY_MAGIC_EOF;
+      else if (matchlet->range_length == -1)
+        return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+      c = getc_unlocked (fp);
+    }
+
+  if (c == '\n')
+    {
+      /* We clean up the matchlet, byte swapping if needed */
+      if (matchlet->word_size > 1)
+        {
+          if (matchlet->value_length % matchlet->word_size != 0)
+            return THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+
+          if (G_BYTE_ORDER != G_BIG_ENDIAN)
+            {
+              for (i = 0; i < matchlet->value_length; i += matchlet->word_size)
+                {
+                  if (matchlet->word_size == 2)
+                    *((guint16 *) matchlet->value + i) = GUINT16_FROM_BE (*((guint16 *) (matchlet->value + i)));
+                  else if (matchlet->word_size == 4)
+                    *((guint32 *) matchlet->value + i) = GUINT32_FROM_BE (*((guint32 *) (matchlet->value + i)));
+                  if (matchlet->mask)
+                    {
+                      if (matchlet->word_size == 2)
+                        *((guint16 *) matchlet->mask + i) = GUINT16_FROM_BE (*((guint16 *) (matchlet->mask + i)));
+                      else if (matchlet->word_size == 4)
+                        *((guint32 *) matchlet->mask + i) = GUINT32_FROM_BE (*((guint32 *) (matchlet->mask + i)));
+
+                    }
+                }
+            }
+        }
+
+      match->matchlets = g_list_append (match->matchlets, matchlet);
+
+      return THUNAR_VFS_MIME_LEGACY_MAGIC_MAGIC;
+    }
+
+  return (c == EOF) ? THUNAR_VFS_MIME_LEGACY_MAGIC_EOF : THUNAR_VFS_MIME_LEGACY_MAGIC_ERROR;
+}
+
+
+
 /**
  * thunar_vfs_mime_legacy_new:
  * @directory : an XDG mime base directory.
@@ -636,6 +1178,9 @@ thunar_vfs_mime_legacy_new (const gchar *directory)
   /* parse the subclasses file (optional) */
   thunar_vfs_mime_legacy_parse_subclasses (legacy, directory);
 
+  /* parse the magic file (optional) */
+  thunar_vfs_mime_legacy_parse_magic (legacy, directory);
+
   /* we got it */
   return THUNAR_VFS_MIME_PROVIDER (legacy);
 }