X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=libdocument%2Fev-file-helpers.c;h=edd4e4fd0adc2414e6918cab61dc7bceb4ce75e8;hb=2297bff1e7d745f0f837d44feeda03244368d7f1;hp=4816db0e51edaca16ee4d0e6ef36c65ba69557b3;hpb=0f1c723ad2fe48a0f22e32619985f93ebb2e02ef;p=evince.git diff --git a/libdocument/ev-file-helpers.c b/libdocument/ev-file-helpers.c index 4816db0e..edd4e4fd 100644 --- a/libdocument/ev-file-helpers.c +++ b/libdocument/ev-file-helpers.c @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -33,7 +33,7 @@ static gchar *tmp_dir = NULL; -/** +/* * ev_dir_ensure_exists: * @dir: the directory name * @mode: permissions to use when creating the directory @@ -43,10 +43,10 @@ static gchar *tmp_dir = NULL; * * Returns: %TRUE on success, or %FALSE on error with @error filled in */ -gboolean -ev_dir_ensure_exists (const gchar *dir, - int mode, - GError **error) +static gboolean +_ev_dir_ensure_exists (const gchar *dir, + int mode, + GError **error) { int errsv; char *display_name; @@ -79,7 +79,7 @@ ev_dir_ensure_exists (const gchar *dir, * Returns: the tmp directory, or %NULL with @error filled in if the * directory could not be created */ -const char * +static const char * _ev_tmp_dir (GError **error) { @@ -92,7 +92,7 @@ _ev_tmp_dir (GError **error) g_free (dirname); } - if (!ev_dir_ensure_exists (tmp_dir, 0700, error)) + if (!_ev_dir_ensure_exists (tmp_dir, 0700, error)) return NULL; return tmp_dir; @@ -195,6 +195,91 @@ ev_mkstemp_file (const char *template, return file; } +/** + * This function is copied from + * http://bugzilla.gnome.org/show_bug.cgi?id=524831 + * and renamed from g_mkdtemp to _ev_g_mkdtemp. + * + * If/when this function gets added to glib, it can be removed from + * evince' sources. + * + * + * g_mkdtemp: + * @tmpl: template directory name + * + * Creates a temporary directory. See the mkdtemp() documentation + * on most UNIX-like systems. + * + * The parameter is a string that should follow the rules for + * mkdtemp() templates, i.e. contain the string "XXXXXX". g_mkdtemp() + * is slightly more flexible than mkdtemp() in that the sequence does + * not have to occur at the very end of the template. The X string + * will be modified to form the name of a directory that didn't + * already exist. The string should be in the GLib file name + * encoding. Most importantly, on Windows it should be in UTF-8. + * + * Return value: If a temporary directory was successfully created, + * @tmpl will be returned with the XXXXXX string modified in such a + * way as to make the path unique. In case of errors, %NULL is + * returned. + */ +static gchar * +_ev_g_mkdtemp (gchar *tmpl) +{ + static const char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static const int NLETTERS = sizeof (letters) - 1; + static int counter = 0; + char *XXXXXX; + GTimeVal tv; + glong value; + int count; + + /* find the last occurrence of "XXXXXX" */ + XXXXXX = g_strrstr (tmpl, "XXXXXX"); + + if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6)) + { + errno = EINVAL; + return NULL; + } + + /* Get some more or less random data. */ + g_get_current_time (&tv); + value = (tv.tv_usec ^ tv.tv_sec) + counter++; + + for (count = 0; count < 100; value += 7777, ++count) + { + glong v = value; + + /* Fill in the random bits. */ + XXXXXX[0] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[1] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[2] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[3] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[4] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[5] = letters[v % NLETTERS]; + + /* tmpl is in UTF-8 on Windows, thus use g_mkdir() */ + if (g_mkdir (tmpl, 0700) == 0) + return tmpl; + + if (errno != EEXIST) + /* Any other error will apply also to other names we might + * try, and there are 2^32 or so of them, so give up now. + */ + return NULL; + } + + /* We got out of the loop because we ran out of combinations to try. */ + errno = EEXIST; + return NULL; +} + /** * ev_mkdtemp: * @template: a template string; must end in 'XXXXXX' @@ -216,7 +301,7 @@ ev_mkdtemp (const char *template, return NULL; name = g_build_filename (tmp, template, NULL); - if (mkdtemp (name) == NULL) { + if (_ev_g_mkdtemp (name) == NULL) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), @@ -234,13 +319,13 @@ ev_mkdtemp (const char *template, void ev_tmp_filename_unlink (const gchar *filename) { - const gchar *tempdir; - if (!filename) return; - tempdir = g_get_tmp_dir (); - if (g_str_has_prefix (filename, tempdir) == 0) { + if (!tmp_dir) + return; + + if (g_str_has_prefix (filename, tmp_dir)) { g_unlink (filename); } } @@ -284,6 +369,25 @@ ev_tmp_uri_unlink (const gchar *uri) g_object_unref (file); } +gboolean +ev_file_is_temp (GFile *file) +{ + gchar *path; + gboolean retval; + + if (!g_file_is_native (file)) + return FALSE; + + path = g_file_get_path (file); + if (!path) + return FALSE; + + retval = g_str_has_prefix (path, g_get_tmp_dir ()); + g_free (path); + + return retval; +} + /** * ev_xfer_uri_simple: * @from: the source URI @@ -312,9 +416,7 @@ ev_xfer_uri_simple (const char *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, error); @@ -353,6 +455,7 @@ get_mime_type_from_uri (const gchar *uri, GError **error) static gchar * get_mime_type_from_data (const gchar *uri, GError **error) { +#ifndef G_OS_WIN32 GFile *file; GFileInputStream *input_stream; gssize size_read; @@ -392,6 +495,13 @@ get_mime_type_from_data (const gchar *uri, GError **error) mime_type = g_content_type_get_mime_type (content_type); g_free (content_type); return mime_type; +#else + /* + * On Windows, the implementation of g_content_type_guess() is too limited at the moment, so we do not + * use it and fall back to get_mime_type_from_uri() + */ + return get_mime_type_from_uri (uri, error); +#endif /* G_OS_WIN32 */ } /**