diff --git a/lib/mu-maildir.c b/lib/mu-maildir.c index 77262ed3..32e8ee83 100644 --- a/lib/mu-maildir.c +++ b/lib/mu-maildir.c @@ -1,7 +1,7 @@ /* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/ /* -** Copyright (C) 2008-2013 Dirk-Jan C. Binnema +** Copyright (C) 2008-2015 Dirk-Jan C. Binnema ** ** This program is free software; you can redistribute it and/or modify it ** under the terms of the GNU General Public License as published by the @@ -807,9 +807,30 @@ mu_maildir_get_new_path (const char *oldpath, const char *new_mdir, return newpath; } + +static gint64 +get_file_size (const char* path) +{ + int rv; + struct stat statbuf; + + rv = stat (path, &statbuf); + if (rv != 0) { + /* g_warning ("error: %s", strerror (errno)); */ + return -1; + } + + return (gint64)statbuf.st_size; +} + + + + static gboolean msg_move_check_pre (const gchar *src, const gchar *dst, GError **err) { + gint size1, size2; + if (!g_path_is_absolute(src)) return mu_util_g_set_error (err, MU_ERROR_FILE, @@ -824,7 +845,16 @@ msg_move_check_pre (const gchar *src, const gchar *dst, GError **err) return mu_util_g_set_error (err, MU_ERROR_FILE, "cannot read %s", src); - if (access (dst, F_OK) == 0) + if (access (dst, F_OK) != 0) + return TRUE; + + /* target exist; we simply overwrite it, unless target has a different + * size. ignore the exceedingly rare case where have duplicate message + * file names with different content yet the same length. (md5 etc. is a + * bit slow) */ + size1 = get_file_size (src); + size2 = get_file_size (dst); + if (size1 != size2) return mu_util_g_set_error (err, MU_ERROR_FILE, "%s already exists", dst); diff --git a/lib/mu-maildir.h b/lib/mu-maildir.h index f6c7de5d..8864781e 100644 --- a/lib/mu-maildir.h +++ b/lib/mu-maildir.h @@ -1,5 +1,5 @@ /* -** Copyright (C) 2008-2013 Dirk-Jan C. Binnema +** Copyright (C) 2008-2015 Dirk-Jan C. Binnema ** ** This program is free software; you can redistribute it and/or modify it ** under the terms of the GNU General Public License as published by the @@ -167,7 +167,8 @@ MuFlags mu_maildir_get_flags_from_path (const char* pathname); * error. */ char* mu_maildir_get_new_path (const char *oldpath, const char *new_mdir, - MuFlags new_flags, gboolean new_name); + MuFlags new_flags, gboolean new_name) + G_GNUC_WARN_UNUSED_RESULT; /** * get the maildir for a certain message path, ie, the path *before* @@ -177,12 +178,13 @@ char* mu_maildir_get_new_path (const char *oldpath, const char *new_mdir, * * @return the maildir (free with g_free), or NULL in case of error */ -char* mu_maildir_get_maildir_from_path (const char* path); +char* mu_maildir_get_maildir_from_path (const char* path) + G_GNUC_WARN_UNUSED_RESULT; /** - * move a message file to another maildir; the function returns the full - * path to the new message. + * move a message file to another maildir; the function returns the full path to + * the new message. if the target file already exists, it is overwritten. * * @param msgpath an absolute file system path to an existing message in an * actual maildir @@ -193,7 +195,7 @@ char* mu_maildir_get_maildir_from_path (const char* path); * of the message are affected; note that this may still involve a * moved to another directory (say, from new/ to cur/) * @param flags to set for the target (influences the filename, path) - * @param ignore_dups whether to silent ignore the src=target case + * @param ignore_dups whether to silently ignore the src=target case * (and return TRUE) * @param new_name whether to create a new unique name, or keep the * old one @@ -204,7 +206,8 @@ char* mu_maildir_get_maildir_from_path (const char* path); */ gchar* mu_maildir_move_message (const char* oldpath, const char* targetmdir, MuFlags newflags, gboolean ignore_dups, - gboolean new_name, GError **err); + gboolean new_name, GError **err) + G_GNUC_WARN_UNUSED_RESULT; G_END_DECLS