diff options
Diffstat (limited to 'src/update-desktop-database.c')
-rw-r--r-- | src/update-desktop-database.c | 265 |
1 files changed, 3 insertions, 262 deletions
diff --git a/src/update-desktop-database.c b/src/update-desktop-database.c index 92cb9a3..260d79a 100644 --- a/src/update-desktop-database.c +++ b/src/update-desktop-database.c @@ -1,12 +1,11 @@ -/* update-desktop-database.c - maintains mimetype<->desktop mapping cache - * vim: set ts=2 sw=2 et: */ - /* * Copyright (C) 2004-2006 Red Hat, Inc. * Copyright (C) 2006, 2008 Vincent Untz + * Copyright © 2013 Canonical Limited * * Program written by Ray Strode <rstrode@redhat.com> * Vincent Untz <vuntz@gnome.org> + * Ryan Lortie <desrt@desrt.ca> * * update-desktop-database is free software; you can redistribute it * and/or modify it under the terms of the GNU General Public License as @@ -25,21 +24,12 @@ */ #include <config.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> #include <glib.h> #include <glib/gi18n.h> -#include "keyfileutils.h" -#include "mimeutils.h" +#include "mime-cache.h" -#define NAME "update-desktop-database" #define CACHE_FILENAME "mimeinfo.cache" static gboolean verbose = FALSE, quiet = FALSE; @@ -59,255 +49,6 @@ log_handler (const gchar *log_domain, g_log_default_handler (log_domain, log_level, message, NULL); } -static void -list_free_deep (gpointer key, GList *l, gpointer data) -{ - g_list_foreach (l, (GFunc)g_free, NULL); - g_list_free (l); -} - -static void -cache_desktop_file (GHashTable *mime_types_map, - const char *desktop_file, - const char *mime_type, - GError **error) -{ - GList *desktop_files; - - desktop_files = (GList *) g_hash_table_lookup (mime_types_map, mime_type); - - /* do not add twice a desktop file mentioning the mime type more than once - * (no need to use g_list_find() because we cache all mime types registered - * by a desktop file before moving to another desktop file) */ - if (desktop_files && - strcmp (desktop_file, (const char *) desktop_files->data) == 0) - return; - - desktop_files = g_list_prepend (desktop_files, g_strdup (desktop_file)); - g_hash_table_insert (mime_types_map, g_strdup (mime_type), desktop_files); -} - - -static void -process_desktop_file (GHashTable *mime_types_map, - const char *desktop_file, - const char *name, - GError **error) -{ - GError *load_error; - GKeyFile *keyfile; - char **mime_types; - int i; - - keyfile = g_key_file_new (); - - load_error = NULL; - g_key_file_load_from_file (keyfile, desktop_file, - G_KEY_FILE_NONE, &load_error); - - if (load_error != NULL) - { - g_propagate_error (error, load_error); - return; - } - - /* Hidden=true means that the .desktop file should be completely ignored */ - if (g_key_file_get_boolean (keyfile, GROUP_DESKTOP_ENTRY, "Hidden", NULL)) - { - g_key_file_free (keyfile); - return; - } - - mime_types = g_key_file_get_string_list (keyfile, - GROUP_DESKTOP_ENTRY, - "MimeType", NULL, &load_error); - - g_key_file_free (keyfile); - - if (load_error != NULL) - { - g_propagate_error (error, load_error); - return; - } - - for (i = 0; mime_types[i] != NULL; i++) - { - char *mime_type; - MimeUtilsValidity valid; - char *valid_error; - - mime_type = g_strchomp (mime_types[i]); - valid = mu_mime_type_is_valid (mime_types[i], &valid_error); - switch (valid) - { - case MU_VALID: - break; - case MU_DISCOURAGED: - g_warning (_("Warning in file \"%s\": usage of MIME type \"%s\" is " - "discouraged (%s)\n"), - desktop_file, mime_types[i], valid_error); - g_free (valid_error); - break; - case MU_INVALID: - g_warning (_("Error in file \"%s\": \"%s\" is an invalid MIME type " - "(%s)\n"), - desktop_file, mime_types[i], valid_error); - g_free (valid_error); - /* not a break: we continue to the next mime type */ - continue; - default: - g_assert_not_reached (); - } - - cache_desktop_file (mime_types_map, name, mime_type, &load_error); - - if (load_error != NULL) - { - g_propagate_error (error, load_error); - g_strfreev (mime_types); - return; - } - } - g_strfreev (mime_types); -} - -static void -process_desktop_files (GHashTable *mime_types_map, - const char *desktop_dir, - const char *prefix, - GError **error) -{ - GError *process_error; - GDir *dir; - const char *filename; - - process_error = NULL; - dir = g_dir_open (desktop_dir, 0, &process_error); - - if (process_error != NULL) - { - g_propagate_error (error, process_error); - return; - } - - while ((filename = g_dir_read_name (dir)) != NULL) - { - char *full_path, *name; - - full_path = g_build_filename (desktop_dir, filename, NULL); - - if (g_file_test (full_path, G_FILE_TEST_IS_DIR)) - { - char *sub_prefix; - - sub_prefix = g_strdup_printf ("%s%s-", prefix, filename); - - process_desktop_files (mime_types_map, full_path, sub_prefix, &process_error); - g_free (sub_prefix); - - if (process_error != NULL) - { - g_warning (_("Could not process directory \"%s\": %s\n"), full_path, process_error->message); - g_error_free (process_error); - process_error = NULL; - } - g_free (full_path); - continue; - } - else if (!g_str_has_suffix (filename, ".desktop")) - { - g_free (full_path); - continue; - } - - name = g_strdup_printf ("%s%s", prefix, filename); - process_desktop_file (mime_types_map, full_path, name, &process_error); - g_free (name); - - if (process_error != NULL) - { - if (!g_error_matches (process_error, - G_KEY_FILE_ERROR, - G_KEY_FILE_ERROR_KEY_NOT_FOUND)) - { - g_warning (_("Could not parse file \"%s\": %s\n"), full_path, process_error->message); - } - else - { - g_debug (_("File \"%s\" lacks MimeType key\n"), full_path); - } - - g_error_free (process_error); - process_error = NULL; - } - - g_free (full_path); - } - - g_dir_close (dir); -} - -static void -add_mime_type (const char *mime_type, GList *desktop_files, GString *str) -{ - GList *desktop_file; - - g_string_append (str, mime_type); - g_string_append_c (str, '='); - for (desktop_file = desktop_files; - desktop_file != NULL; - desktop_file = desktop_file->next) - { - g_string_append (str, (const char *) desktop_file->data); - g_string_append_c (str, ';'); - } - g_string_append_c (str, '\n'); -} - -static GBytes * -mime_cache_build (const char *desktop_dir, - GError **error) -{ - GHashTable *mime_types_map; - GError *update_error; - GList *keys, *key; - GString *contents; - GBytes *result; - gsize size; - - result = NULL; - - mime_types_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - - update_error = NULL; - process_desktop_files (mime_types_map, desktop_dir, "", &update_error); - - if (update_error != NULL) - { - g_propagate_error (error, update_error); - goto out; - } - - contents = g_string_new ("[MIME Cache]\n"); - - keys = g_hash_table_get_keys (mime_types_map); - keys = g_list_sort (keys, (GCompareFunc) g_strcmp0); - - for (key = keys; key != NULL; key = key->next) - add_mime_type (key->data, g_hash_table_lookup (mime_types_map, key->data), contents); - - g_list_free (keys); - - size = contents->len; - result = g_bytes_new_take (g_string_free (contents, FALSE), size); - -out: - g_hash_table_foreach (mime_types_map, (GHFunc) list_free_deep, NULL); - g_hash_table_unref (mime_types_map); - - return result; -} - static gboolean update_database (const char *desktop_dir, GError **error) |