X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=libdocument%2Fev-file-helpers.c;h=e48ce9d081bc42bc8a95116b7200ac09ebf6a181;hb=22a76eb4d52da8548b31c215a117ef7048573695;hp=9bf2e463a9852872d92f61ecb8a777e451adfc2e;hpb=b346c5664d27a77e9068ea91eaf9a0c0d6210b0f;p=evince.git diff --git a/libdocument/ev-file-helpers.c b/libdocument/ev-file-helpers.c index 9bf2e463..e48ce9d0 100644 --- a/libdocument/ev-file-helpers.c +++ b/libdocument/ev-file-helpers.c @@ -29,65 +29,45 @@ #include #include #include -#include -#include -#include -#include + +#if WITH_GNOME +#include +#endif #include "ev-file-helpers.h" -static gchar *dot_dir = NULL; static gchar *tmp_dir = NULL; static gint count = 0; -static gboolean -ensure_dir_exists (const char *dir) +gboolean +ev_dir_ensure_exists (const gchar *dir, + int mode) { - if (g_file_test (dir, G_FILE_TEST_IS_DIR)) - return TRUE; - - if (g_mkdir (dir, 488) == 0) + if (g_mkdir_with_parents (dir, mode) == 0) return TRUE; if (errno == EEXIST) return g_file_test (dir, G_FILE_TEST_IS_DIR); - g_warning ("Failed to create directory %s: %s", dir, strerror (errno)); + g_warning ("Failed to create directory %s: %s", dir, g_strerror (errno)); return FALSE; } -const gchar * -ev_dot_dir (void) -{ - if (dot_dir == NULL) { - gboolean exists; - - dot_dir = g_build_filename (gnome_user_dir_get (), - "evince", - NULL); - - exists = ensure_dir_exists (dot_dir); - if (!exists) - exit (1); - } - - return dot_dir; -} - const gchar * ev_tmp_dir (void) { if (tmp_dir == NULL) { gboolean exists; - gchar *dirname; + gchar *dirname, *prgname; - dirname = g_strdup_printf ("evince-%u", getpid ()); + prgname = g_get_prgname (); + dirname = g_strdup_printf ("%s-%u", prgname ? prgname : "unknown", getpid ()); tmp_dir = g_build_filename (g_get_tmp_dir (), dirname, NULL); g_free (dirname); - exists = ensure_dir_exists (tmp_dir); + exists = ev_dir_ensure_exists (tmp_dir, 0700); g_assert (exists); } @@ -95,23 +75,34 @@ ev_tmp_dir (void) } void -ev_file_helpers_init (void) +_ev_file_helpers_init (void) { } void -ev_file_helpers_shutdown (void) +_ev_file_helpers_shutdown (void) { if (tmp_dir != NULL) g_rmdir (tmp_dir); g_free (tmp_dir); - g_free (dot_dir); - - dot_dir = NULL; tmp_dir = NULL; } +GFile * +ev_tmp_file_get (const gchar *prefix) +{ + gchar *path; + GFile *file; + + path = ev_tmp_filename (prefix); + file = g_file_new_for_path (path); + + g_free (path); + + return file; +} + gchar * ev_tmp_filename (const gchar *prefix) { @@ -135,58 +126,172 @@ ev_tmp_filename (const gchar *prefix) return filename; } +/* Remove a local temp file created by evince */ +void +ev_tmp_filename_unlink (const gchar *filename) +{ + const gchar *tempdir; + + if (!filename) + return; + + tempdir = g_get_tmp_dir (); + if (g_ascii_strncasecmp (filename, tempdir, strlen (tempdir)) == 0) { + g_unlink (filename); + } +} + +void +ev_tmp_file_unlink (GFile *file) +{ + gboolean res; + GError *error = NULL; + + if (!file) + return; + + res = g_file_delete (file, NULL, &error); + if (!res) { + char *uri; + + uri = g_file_get_uri (file); + g_warning ("Unable to delete temp file %s: %s\n", uri, error->message); + g_free (uri); + g_error_free (error); + } +} + +void +ev_tmp_uri_unlink (const gchar *uri) +{ + GFile *file; + + if (!uri) + return; + + file = g_file_new_for_uri (uri); + if (!g_file_is_native (file)) { + g_warning ("Attempting to delete non native uri: %s\n", uri); + g_object_unref (file); + return; + } + + ev_tmp_file_unlink (file); + g_object_unref (file); +} + gboolean ev_xfer_uri_simple (const char *from, const char *to, GError **error) { - GnomeVFSResult result; - GnomeVFSURI *source_uri; - GnomeVFSURI *target_uri; + GFile *source_file; + GFile *target_file; + GError *ioerror = NULL; + gboolean result; if (!from) return FALSE; - source_uri = gnome_vfs_uri_new (from); - target_uri = gnome_vfs_uri_new (to); - - result = gnome_vfs_xfer_uri (source_uri, target_uri, - GNOME_VFS_XFER_DEFAULT | GNOME_VFS_XFER_FOLLOW_LINKS, - GNOME_VFS_XFER_ERROR_MODE_ABORT, - GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, - NULL, - NULL); - gnome_vfs_uri_unref (target_uri); - gnome_vfs_uri_unref (source_uri); + source_file = g_file_new_for_uri (from); + target_file = g_file_new_for_uri (to); + + result = g_file_copy (source_file, target_file, +#if GLIB_CHECK_VERSION(2,19,0) + G_FILE_COPY_TARGET_DEFAULT_PERMS | +#endif + G_FILE_COPY_OVERWRITE, + NULL, NULL, NULL, &ioerror); + + g_object_unref (target_file); + g_object_unref (source_file); - if (result != GNOME_VFS_OK) - g_set_error (error, - G_FILE_ERROR, - G_FILE_ERROR_FAILED, - gnome_vfs_result_to_string (result)); - return (result == GNOME_VFS_OK); + if (!result) { + g_propagate_error (error, ioerror); + } + return result; } +static gchar * +get_mime_type_from_uri (const gchar *uri, GError **error) +{ + GFile *file; + GFileInfo *file_info; + gchar *mime_type; + + file = g_file_new_for_uri (uri); + file_info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + 0, NULL, error); + g_object_unref (file); + + if (file_info == NULL) + return NULL; + + mime_type = g_content_type_get_mime_type ( + g_file_info_get_content_type (file_info)); + g_object_unref (file_info); + + return mime_type; +} + +static gchar * +get_mime_type_from_data (const gchar *uri, GError **error) +{ + GFile *file; + GFileInputStream *input_stream; + gssize size_read; + guchar buffer[1024]; + + file = g_file_new_for_uri (uri); + + input_stream = g_file_read (file, NULL, error); + if (!input_stream) { + g_object_unref (file); + return NULL; + } + + size_read = g_input_stream_read (G_INPUT_STREAM (input_stream), + buffer, 1024, NULL, NULL); + g_input_stream_close (G_INPUT_STREAM (input_stream), NULL, error); + + g_object_unref (file); + + if (size_read == -1) + return NULL; + + return g_content_type_guess (NULL, /* no filename */ + buffer, 1024, + NULL); +} + +gchar * +ev_file_get_mime_type (const gchar *uri, + gboolean fast, + GError **error) +{ + return fast ? get_mime_type_from_uri (uri, error) : get_mime_type_from_data (uri, error); +} + /* Compressed files support */ #define BZIPCOMMAND "bzip2" #define GZIPCOMMAND "gzip" -#define N_ARGS 5 +#define N_ARGS 4 #define BUFFER_SIZE 1024 -gchar * -ev_file_uncompress (const gchar *uri, - EvCompressionType type, - GError **error) +static gchar * +compression_run (const gchar *uri, + EvCompressionType type, + gboolean compress, + GError **error) { gchar *argv[N_ARGS]; - gchar *uri_unc = NULL; - gchar *filename, *filename_unc; + gchar *uri_dst = NULL; + gchar *filename, *filename_dst; gchar *cmd; gint fd, pout; - g_return_val_if_fail (uri != NULL, NULL); - if (type == EV_COMPRESSION_NONE) return NULL; @@ -194,27 +299,25 @@ ev_file_uncompress (const gchar *uri, if (!cmd) return NULL; - filename = g_filename_from_uri (uri, NULL, NULL); if (!filename) { g_free (cmd); return NULL; } - filename_unc = g_build_filename (ev_tmp_dir (), "evinceXXXXXX", NULL); - fd = g_mkstemp (filename_unc); + filename_dst = g_build_filename (ev_tmp_dir (), "evinceXXXXXX", NULL); + fd = g_mkstemp (filename_dst); if (fd < 0) { g_free (cmd); g_free (filename); - g_free (filename_unc); + g_free (filename_dst); return NULL; } - + argv[0] = cmd; - argv[1] = "-cd"; + argv[1] = compress ? "-c" : "-cd"; argv[2] = filename; - argv[3] = filename_unc; - argv[4] = NULL; + argv[3] = NULL; if (g_spawn_async_with_pipes (NULL, argv, NULL, G_SPAWN_STDERR_TO_DEV_NULL, @@ -246,7 +349,7 @@ ev_file_uncompress (const gchar *uri, break; } } while (bytes_read > 0); - + g_io_channel_unref (in); g_io_channel_unref (out); } @@ -254,13 +357,32 @@ ev_file_uncompress (const gchar *uri, close (fd); if (*error == NULL) { - uri_unc = g_filename_to_uri (filename_unc, - NULL, NULL); + uri_dst = g_filename_to_uri (filename_dst, NULL, NULL); } g_free (cmd); g_free (filename); - g_free (filename_unc); + g_free (filename_dst); + + return uri_dst; +} + +gchar * +ev_file_uncompress (const gchar *uri, + EvCompressionType type, + GError **error) +{ + g_return_val_if_fail (uri != NULL, NULL); + + return compression_run (uri, type, FALSE, error); +} + +gchar * +ev_file_compress (const gchar *uri, + EvCompressionType type, + GError **error) +{ + g_return_val_if_fail (uri != NULL, NULL); - return uri_unc; + return compression_run (uri, type, TRUE, error); }