Implement safe_fclose() so we can respect the "Metadata handling"
authorColin Leroy <colin@colino.net>
Fri, 5 Oct 2018 21:01:46 +0000 (23:01 +0200)
committerAndrej Kacian <ticho@claws-mail.org>
Tue, 16 Oct 2018 16:45:37 +0000 (18:45 +0200)
preference for every data file we write into.

48 files changed:
src/Makefile.am
src/addrbook.c
src/addrindex.c
src/common/Makefile.am
src/common/log.c
src/common/prefs.c
src/common/ssl_certificate.c
src/common/tags.c
src/common/template.c
src/common/utils.c
src/compose.c
src/etpan/imap-thread.c
src/exporthtml.c
src/exportldif.c
src/ldapquery.c
src/main.c
src/mbox.c
src/messageview.c
src/mh.c
src/msgcache.c
src/news.c
src/partial_download.c
src/plugins/acpi_notifier/acpi_notifier.c
src/plugins/bogofilter/bogofilter.c
src/plugins/fancy/claws.def
src/plugins/fancy/fancy_viewer.c
src/plugins/libravatar/claws.def
src/plugins/libravatar/libravatar_image.c
src/plugins/libravatar/libravatar_missing.c
src/plugins/mailmbox/claws.def
src/plugins/mailmbox/mailmbox_folder.c
src/plugins/pgpinline/claws.def
src/plugins/pgpinline/pgpinline.c
src/plugins/pgpmime/claws.def
src/plugins/pgpmime/pgpmime.c
src/plugins/rssyl/claws.def
src/plugins/rssyl/opml_export.c
src/plugins/rssyl/rssyl_add_item.c
src/plugins/rssyl/rssyl_deleted.c
src/plugins/smime/claws.def
src/plugins/smime/smime.c
src/plugins/vcalendar/claws.def
src/plugins/vcalendar/vcal_meeting_gtk.c
src/pop.c
src/prefs_common.c
src/procmsg.c
src/safe_fclose.c [new file with mode: 0644]
src/safe_fclose.h [new file with mode: 0644]

index 9844f304fe8c39ad4735f432f04f58265b4f3b2d..b19eccd267fc6d8a09545e194aafd6cc7beabe1b 100644 (file)
@@ -228,6 +228,7 @@ claws_mail_SOURCES = \
        quote_fmt_parse.y \
        recv.c \
        remotefolder.c \
+       safe_fclose.c \
        send_message.c \
        setup.c \
        sourcewindow.c \
@@ -348,6 +349,7 @@ claws_mailinclude_HEADERS = \
        quote_fmt_parse.h \
        recv.h \
        remotefolder.h \
+       safe_fclose.h \
        send_message.h \
        setup.h \
        sourcewindow.h \
index 274d4ac4431ea217c161d107ff8f1a7ff83b85d4..c519eb7142cc547d47726b5382d34a47a54d9db4 100644 (file)
@@ -33,6 +33,7 @@
 #include "addrcache.h"
 #include "addrbook.h"
 #include "adbookbase.h"
+#include "safe_fclose.h"
 
 #ifndef DEV_STANDALONE
 #include "prefs_gtk.h"
@@ -1318,7 +1319,7 @@ static gint addrbook_write_to(AddressBookFile *book, gchar *newFile)
 
                book->retVal = MGU_SUCCESS;
 #ifdef DEV_STANDALONE
-               fclose(fp);
+               safe_fclose(fp);
 #else
                if (prefs_file_close( pfile ) < 0)
                        book->retVal = MGU_ERROR_WRITE;
index 80129968e87c5b1636287244f2c164a17421058c..fda0bcd62286f4ea7475854837dbb4ea090f1041 100644 (file)
@@ -43,6 +43,7 @@
 #include "utils.h"
 #include "alertpanel.h"
 #include "passwordstore.h"
+#include "safe_fclose.h"
 
 #ifndef DEV_STANDALONE
 #include "prefs_gtk.h"
@@ -1782,7 +1783,7 @@ static gint addrindex_write_to( AddressIndex *addrIndex, const gchar *newFile )
 
                addrIndex->retVal = MGU_SUCCESS;
 #ifdef DEV_STANDALONE
-               fclose( fp );
+               safe_fclose( fp );
 #else
                if( prefs_file_close( pfile ) < 0 ) {
                        addrIndex->retVal = MGU_ERROR_WRITE;
index 5c4f249573f42fa8a924a1c5ec414800fcc252c9..d1fd7998d1c0e2a4207f9dd3708b881148f5eb93 100644 (file)
@@ -87,6 +87,7 @@ clawscommoninclude_HEADERS = $(arch_headers) \
        unmime.h
 
 AM_CPPFLAGS = \
+       -I$(srcdir)/.. \
        -I$(top_srcdir)/intl \
        $(GLIB_CFLAGS) \
        $(VALGRIND_CFLAGS) \
index 286b836d6d75a8f40884bdcaf670b616a4047170..1003d51a29e460dadab3e103db4c849acbc52d81 100644 (file)
@@ -35,6 +35,7 @@
 #include "utils.h"
 #include "log.h"
 #include "hooks.h"
+#include "safe_fclose.h"
 
 #define FWRITE(_b,_s,_n,_f)    if (fwrite(_b,_s,_n,_f) != _n) { \
                                        g_message("log fwrite failed!\n"); \
@@ -136,7 +137,7 @@ void set_log_file(LogInstance instance, const gchar *filename)
 void close_log_file(LogInstance instance)
 {
        if (log_fp[instance]) {
-               fclose(log_fp[instance]);
+               safe_fclose(log_fp[instance]);
                log_fp[instance] = NULL;
                log_size[instance] = 0;
                g_free(log_filename[instance]);
index 23bcc220861a05d8c89cc18484daafaf78818943..362cbb9ff084423e0134f3e9ec5b68ac187d42ff 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "prefs.h"
 #include "utils.h"
+#include "safe_fclose.h"
 
 static gboolean prefs_is_readonly      (const gchar    *path);
 
@@ -159,17 +160,7 @@ gint prefs_file_close(PrefFile *pfile)
 
        tmppath = g_strconcat(path, ".tmp", NULL);
 
-       
-       if (prefs_common_get_flush_metadata() && fsync(fileno(fp)) < 0) {
-               FILE_OP_ERROR(tmppath, "fsync");
-               fclose(fp);
-               claws_unlink(tmppath);
-               g_free(path);
-               g_free(tmppath);
-               return -1;
-       }
-
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                FILE_OP_ERROR(tmppath, "fclose");
                claws_unlink(tmppath);
                g_free(path);
index 75b61e6c89c3c87bf7f2f53acd3d2d8d7cae57ed..1f7166257fd3371d8e16d0c14b2dbb91a3cd2920 100644 (file)
@@ -46,6 +46,7 @@
 #include "socket.h"
 #include "hooks.h"
 #include "defs.h"
+#include "safe_fclose.h"
 
 static GHashTable *warned_expired = NULL;
 
@@ -376,7 +377,7 @@ static void ssl_certificate_save (SSLCertificate *cert)
        gnutls_export_X509_fp(fp, cert->x509_cert, GNUTLS_X509_FMT_DER);
 
        g_free(file);
-       fclose(fp);
+       safe_fclose(fp);
 
 }
 
@@ -682,7 +683,7 @@ static void ssl_certificate_save_chain(gnutls_x509_crt_t *certs, gint len, const
 
        }
        if (fp)
-               fclose(fp);
+               safe_fclose(fp);
 }
 
 gboolean ssl_certificate_check (gnutls_x509_crt_t x509_cert, guint status, 
index e68ee647b3580d9c3c78debd54cb3d6074f2a76e..e0f020a99582b56156cc6f3f108ccc8e424b96b9 100644 (file)
@@ -40,6 +40,7 @@
 #include "defs.h"
 #include "utils.h"
 #include "tags.h"
+#include "safe_fclose.h"
 
 static GHashTable *tags_table = NULL;
 static GHashTable *tags_reverse_table = NULL;
@@ -146,7 +147,7 @@ void tags_write_tags(void)
                return;
        }
        
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                FILE_OP_ERROR(file, "fclose");
                g_free(file);
                g_free(file_new);
index 9d53d883ed085f8ebc380e16ac1a1395c5865554..dfd96032f4dd4142c3da0b754915a96bdd8207c5 100644 (file)
@@ -29,6 +29,7 @@
 #include "utils.h"
 #include "template.h"
 #include "codeconv.h"
+#include "safe_fclose.h"
 
 static GSList *template_list;
 
@@ -283,7 +284,7 @@ static void template_write_config(GSList *tmpl_list)
                } else {
                        TRY(fwrite("", sizeof(gchar), 1, fp) == 1);
                }
-               TRY_NO_CLOSE(fclose(fp) != EOF);
+               TRY_NO_CLOSE(safe_fclose(fp) != EOF);
 
                if (new) {
                        if (rename_force(new, filename) < 0) {
index 38335452eadcd14c51ee2c4ff09a08da0243f2ff..e3ba80c17fbcec87c7356679a8a2ba801f79a016 100644 (file)
@@ -85,6 +85,8 @@
 #include "socket.h"
 #include "codeconv.h"
 #include "tlds.h"
+#include "timing.h"
+#include "safe_fclose.h"
 
 #define BUFFSIZE       8192
 
@@ -340,7 +342,7 @@ gint file_strip_crs(const gchar *file)
        }
 
        fclose(fp);
-       if (fclose(outfp) == EOF) {
+       if (safe_fclose(outfp) == EOF) {
                goto unlinkout;
        }
        
@@ -2523,7 +2525,7 @@ gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup)
                err = TRUE;
        }
        fclose(src_fp);
-       if (fclose(dest_fp) == EOF) {
+       if (safe_fclose(dest_fp) == EOF) {
                FILE_OP_ERROR(dest, "fclose");
                err = TRUE;
        }
@@ -2619,7 +2621,7 @@ gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest)
        if (copy_file_part_to_fp(fp, offset, length, dest_fp) < 0)
                err = TRUE;
 
-       if (fclose(dest_fp) == EOF) {
+       if (safe_fclose(dest_fp) == EOF) {
                FILE_OP_ERROR(dest, "fclose");
                err = TRUE;
        }
@@ -2737,7 +2739,7 @@ gint canonicalize_file(const gchar *src, const gchar *dest)
                err = TRUE;
        }
        fclose(src_fp);
-       if (fclose(dest_fp) == EOF) {
+       if (safe_fclose(dest_fp) == EOF) {
                FILE_OP_ERROR(dest, "fclose");
                err = TRUE;
        }
@@ -2997,7 +2999,7 @@ gint str_write_to_file(const gchar *str, const gchar *file)
                return -1;
        }
 
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                FILE_OP_ERROR(file, "fclose");
                claws_unlink(file);
                return -1;
@@ -4580,7 +4582,7 @@ void mailcap_update_default(const gchar *type, const gchar *command)
        if (fp)
                fclose(fp);
 
-       if (fclose(outfp) == EOF)
+       if (safe_fclose(outfp) == EOF)
                err = TRUE;
                
        if (!err)
index 6694348f578ec17c8d299fe2f0b48b12699b4187..88ff25417434fccceae6be7ac06ad4882429eccb 100644 (file)
 #include "autofaces.h"
 #include "spell_entry.h"
 #include "headers.h"
+#include "safe_fclose.h"
+
 #ifdef USE_LDAP
 #include "password.h"
 #include "ldapserver.h"
@@ -6003,7 +6005,7 @@ static gint compose_write_body_to_file(Compose *compose, const gchar *file)
 
        g_free(chars);
 
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                FILE_OP_ERROR(file, "fclose");
                claws_unlink(file);
                return -1;
@@ -6296,7 +6298,7 @@ static ComposeQueueResult compose_queue_sub(Compose *compose, gint *msgnum, Fold
                g_free(tmp);
                return COMPOSE_QUEUE_ERROR_WITH_ERRNO;
        }
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                FILE_OP_ERROR(tmp, "fclose");
                claws_unlink(tmp);
                g_free(tmp);
@@ -10395,7 +10397,7 @@ gboolean compose_draft (gpointer data, guint action)
                fclose(fp);
                goto warn_err;
        }
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                goto warn_err;
        }
        
index 80279d2596c3e81be40f21e343da4ff114bf5c68..29d03802b60cd3a7e5b67ffd6c209e0cdf3a0b11 100644 (file)
@@ -44,6 +44,7 @@
 #include "utils.h"
 #include "mainwindow.h"
 #include "proxy.h"
+#include "safe_fclose.h"
 #include "ssl.h"
 #include "ssl_certificate.h"
 #include "socket.h"
@@ -2637,7 +2638,7 @@ static void fetch_content_run(struct etpan_thread_op * op)
                        goto fclose;
                }
                
-               r = fclose(f);
+               r = safe_fclose(f);
                if (r == EOF) {
                        result->error = MAILIMAP_ERROR_FETCH;
                        goto unlink;
index 675576f42ec8a132631c6ced437073962928b130..7ed6fc80c25eede59efb02678e164ed5ab5a217b 100644 (file)
@@ -46,6 +46,7 @@
 #include "utils.h"
 #include "exporthtml.h"
 #include "xmlprops.h"
+#include "safe_fclose.h"
 
 #ifdef MKDIR_TAKES_ONE_ARG
 #undef mkdir
@@ -301,7 +302,7 @@ static gint exporthtml_create_css_dfl( const gchar *fileSpec ) {
        fprintf( cssFile, ".tab-attr {\n" );
        fprintf( cssFile, "}\n" );
 
-       fclose( cssFile );
+       safe_fclose( cssFile );
        return MGU_SUCCESS;
 }
 
@@ -365,7 +366,7 @@ static gint exporthtml_create_css_full( const gchar *fileSpec ) {
        fprintf( cssFile, ".tab-attr {\n" );
        fprintf( cssFile, "}\n" );
 
-       fclose( cssFile );
+       safe_fclose( cssFile );
        return MGU_SUCCESS;
 }
 
@@ -994,7 +995,7 @@ void exporthtml_process(
        fprintf( htmlFile, "</body>\n" );
        fprintf( htmlFile, "</html>\n" );
 
-       fclose( htmlFile );
+       safe_fclose( htmlFile );
        ctl->retVal = MGU_SUCCESS;
 
        /* Create stylesheet files */
index d9c1b49e9a3fdbbf8c180cd4f502432e79620d89..eba87379c8345d613f3684b065be9489fdb8c360 100644 (file)
@@ -38,6 +38,7 @@
 #include "exportldif.h"
 #include "xmlprops.h"
 #include "ldif.h"
+#include "safe_fclose.h"
 
 
 #ifdef MKDIR_TAKES_ONE_ARG
@@ -541,7 +542,7 @@ void exportldif_process( ExportLdifCtl *ctl, AddressCache *cache )
 
        rootFolder = cache->rootFolder;
        exportldif_fmt_folder( ctl, ldifFile, rootFolder );
-       fclose( ldifFile );
+       safe_fclose( ldifFile );
        ctl->retVal = MGU_SUCCESS;
 }
 
index b132989bc1e3da81ae60531c333b37f6991cf6df..257ae190f47c2d7fd5452bfc3e6e69bf1dafdbd6 100644 (file)
@@ -38,6 +38,7 @@
 #include "ldapctrl.h"
 #include "ldapserver.h"
 #include "mgutils.h"
+#include "safe_fclose.h"
 
 #include "addritem.h"
 #include "addrcache.h"
@@ -426,7 +427,7 @@ static GSList *ldapqry_add_single_value( LDAP *ld, LDAPMessage *entry, char *att
                                FILE *fp = g_fopen(file, "wb");
                                if (fp) {
                                        fwrite(vals[0]->bv_val, 1, vals[0]->bv_len, fp);
-                                       fclose(fp);
+                                       safe_fclose(fp);
                                }
                                list = g_slist_append( list, file);
                        }
index 398dadd56f96a52d653a5e86ad8b70c119877cf0..8a0ce235f950eb41e28730216d3fc96dad62fdb4 100644 (file)
 #include "advsearch.h"
 #include "avatars.h"
 #include "passwordstore.h"
+#include "safe_fclose.h"
 
 #ifdef HAVE_LIBETPAN
 #include "imap-thread.h"
@@ -477,7 +478,7 @@ static int migrate_common_rc(const gchar *old_rc, const gchar *new_rc)
        g_free(new_plugin_path);
        g_free(old_plugin_path);
        fclose(oldfp);
-       if (fclose(newfp) == EOF)
+       if (safe_fclose(newfp) == EOF)
                err = TRUE;
        
        return (err ? -1:0);
index 9929a29cf243cdec4c4a6a4b7688a5219a545994..ea1138a219893f2c031a8315b9fa19b87b9b7629 100644 (file)
@@ -56,6 +56,7 @@
 #include "filtering.h"
 #include "alertpanel.h"
 #include "statusbar.h"
+#include "safe_fclose.h"
 
 #define MESSAGEBUFSIZE 8192
 
@@ -230,7 +231,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter,
                        return -1;
                }
 
-               if (fclose(tmp_fp) == EOF) {
+               if (safe_fclose(tmp_fp) == EOF) {
                        FILE_OP_ERROR(tmp_file, "fclose");
                        g_warning("can't write to temporary file");
                        fclose(mbox_fp);
@@ -333,7 +334,7 @@ gint lock_mbox(const gchar *base, LockType type)
                        return -1;
                }
 
-               if (fclose(lockfp) == EOF) {
+               if (safe_fclose(lockfp) == EOF) {
                        FILE_OP_ERROR(lockfile, "fclose");
                        g_free(lockfile);
                        return -1;
@@ -509,7 +510,7 @@ gint copy_mbox(gint srcfd, const gchar *dest)
                err = TRUE;
        }
 
-       if (fclose(dest_fp) == EOF) {
+       if (safe_fclose(dest_fp) == EOF) {
                FILE_OP_ERROR(dest, "fclose");
                err = TRUE;
        }
@@ -531,7 +532,7 @@ void empty_mbox(const gchar *mbox)
                g_warning("can't truncate mailbox to zero.");
                return;
        }
-       fclose(fp);
+       safe_fclose(fp);
 }
 
 gint export_list_to_mbox(GSList *mlist, const gchar *mbox)
@@ -657,7 +658,7 @@ gint export_list_to_mbox(GSList *mlist, const gchar *mbox)
 #ifdef HAVE_FGETS_UNLOCKED
                funlockfile(msg_fp);
 #endif
-               fclose(msg_fp);
+               safe_fclose(msg_fp);
                statusbar_progress_all(msgs++,total, 500);
                if (msgs%500 == 0)
                        GTK_EVENTS_FLUSH();
@@ -670,7 +671,7 @@ out:
 #ifdef HAVE_FGETS_UNLOCKED
        funlockfile(mbox_fp);
 #endif
-       fclose(mbox_fp);
+       safe_fclose(mbox_fp);
 
        return err;
 }
index b6966915844e3e35d6a195bd7c86cfa5b3ad9794..0882cc42405761473bcc1fa30265d2f9f8a1e669 100644 (file)
@@ -67,6 +67,8 @@
 #include "statusbar.h"
 #include "folder_item_prefs.h"
 #include "avatars.h"
+#include "safe_fclose.h"
+
 #ifndef USE_ALT_ADDRBOOK
        #include "addressbook.h"
 #else
@@ -1061,7 +1063,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
        if (ok < 0)
                goto FILE_ERROR;        
 
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                FILE_OP_ERROR(tmp, "fclose");
                claws_unlink(tmp);
                return -1;
index 0bf0783ff8c55e0eab5736a92fad60a1fea885e6..713ce0d4872d231454900948ff5b0d5074f04144 100644 (file)
--- a/src/mh.c
+++ b/src/mh.c
@@ -44,6 +44,7 @@
 #include "gtkutils.h"
 #include "timing.h"
 #include "msgcache.h"
+#include "safe_fclose.h"
 
 /* Define possible missing constants for Windows. */
 #ifdef G_OS_WIN32
@@ -1421,11 +1422,7 @@ static void mh_write_sequences(FolderItem *item, gboolean remove_unseen)
                        fclose(mh_sequences_old_fp);
                }
                
-               fflush(mh_sequences_new_fp);
-#if 0
-               fsync(fileno(mh_sequences_new_fp));
-#endif
-               if (fclose(mh_sequences_new_fp) == EOF)
+               if (safe_fclose(mh_sequences_new_fp) == EOF)
                        err = TRUE;
 
                if (!err) {
index edaa0924c703bf558227f0fe86ad72a2262cb691..871c04a25c36060192d0d9491ff91031405fefed 100644 (file)
@@ -47,6 +47,7 @@
 #include "timing.h"
 #include "tags.h"
 #include "prefs_common.h"
+#include "safe_fclose.h"
 
 #ifdef HAVE_FWRITE_UNLOCKED
 #define SC_FWRITE fwrite_unlocked
@@ -1219,29 +1220,14 @@ gint msgcache_write(const gchar *cache_file, const gchar *mark_file, const gchar
        if (write_fps.tags_fp)
                funlockfile(write_fps.tags_fp);
 #endif
-       /* flush buffers */
-       if (write_fps.cache_fp)
-               write_fps.error |= (fflush(write_fps.cache_fp) != 0);
-       if (write_fps.mark_fp)
-               write_fps.error |= (fflush(write_fps.mark_fp) != 0);
-       if (write_fps.tags_fp)
-               write_fps.error |= (fflush(write_fps.tags_fp) != 0);
-
-       /* sync to filesystem */
-       if (prefs_common.flush_metadata && write_fps.cache_fp)
-               write_fps.error |= (fsync(fileno(write_fps.cache_fp)) != 0);
-       if (prefs_common.flush_metadata && write_fps.mark_fp)
-               write_fps.error |= (fsync(fileno(write_fps.mark_fp)) != 0);
-       if (prefs_common.flush_metadata && write_fps.tags_fp)
-               write_fps.error |= (fsync(fileno(write_fps.tags_fp)) != 0);
 
        /* close files */
        if (write_fps.cache_fp)
-               write_fps.error |= (fclose(write_fps.cache_fp) != 0);
+               write_fps.error |= (safe_fclose(write_fps.cache_fp) != 0);
        if (write_fps.mark_fp)
-               write_fps.error |= (fclose(write_fps.mark_fp) != 0);
+               write_fps.error |= (safe_fclose(write_fps.mark_fp) != 0);
        if (write_fps.tags_fp)
-               write_fps.error |= (fclose(write_fps.tags_fp) != 0);
+               write_fps.error |= (safe_fclose(write_fps.tags_fp) != 0);
 
 
        if (write_fps.error != 0) {
index 7d5fbfa0f44efac7feac037aed34c5a58222232e..6c29cfb30c6187e9a1cee47778eddaaa41e22937 100644 (file)
@@ -62,6 +62,7 @@
 #  include "ssl.h"
 #endif
 #include "main.h"
+#include "safe_fclose.h"
 
 #define NNTP_PORT      119
 #ifdef USE_GNUTLS
@@ -702,7 +703,7 @@ GSList *news_get_group_list(Folder *folder)
                        }
                        newsnntp_list_free(grouplist);
                }
-               if (fclose(fp) == EOF) {
+               if (safe_fclose(fp) == EOF) {
                        log_error(LOG_PROTOCOL, ("Can't write newsgroup list\n"));
                        session_destroy(SESSION(session));
                        REMOTE_FOLDER(folder)->session = NULL;
@@ -984,7 +985,7 @@ gint news_cancel_article(Folder * folder, MsgInfo * msginfo)
                return -1;
        }
 
-       if (fclose(tmpfp) == EOF) {
+       if (safe_fclose(tmpfp) == EOF) {
                FILE_OP_ERROR(tmp, "fclose");
                claws_unlink(tmp);
                g_free(tmp);
index e0283cc81a1d5a68552f468b96b9dd649f1be08e..384393ec6382a169a5c0a9be74ed7f505f14fb98 100644 (file)
@@ -63,6 +63,7 @@
 #include "folder.h"
 #include "procheader.h"
 #include "msgcache.h"
+#include "safe_fclose.h"
 
 int partial_msg_in_uidl_list(MsgInfo *msginfo)
 {
@@ -248,7 +249,7 @@ static int partial_uidl_mark_mail(MsgInfo *msginfo, int download)
                        g_free(stat);
                }
        }
-       if (fclose(fpnew) == EOF) {
+       if (safe_fclose(fpnew) == EOF) {
                FILE_OP_ERROR(pathnew, "fclose");
                fclose(fp);
                g_free(path);
@@ -308,7 +309,7 @@ static int partial_uidl_mark_mail(MsgInfo *msginfo, int download)
                        goto bail;
                }
        }
-       if (fclose(fpnew) == EOF) {
+       if (safe_fclose(fpnew) == EOF) {
                FILE_OP_ERROR(pathnew, "fclose");
                fclose(fp);
                g_free(pathnew);
index 50430c65953921cbc2954dc55da5633398d16d11..ee59b2eb64db3c3f819148e4ac9af6f567838a56 100644 (file)
@@ -48,6 +48,7 @@
 #include "folder_item_prefs.h"
 #include "gtk/gtkutils.h"
 #include "gtk/combobox.h"
+#include "safe_fclose.h"
 
 #define PREFS_BLOCK_NAME "AcpiNotifier"
 #define PLUGIN_NAME _("Acpi Notifier")
@@ -659,7 +660,7 @@ static void acpi_set(gboolean on)
                } else {
                        fwrite(acpiprefs.off_param, 1, strlen(acpiprefs.off_param), fp);
                }
-               fclose(fp);
+               safe_fclose(fp);
        } else {
                gchar *cmd = g_strdup_printf("%s %s", 
                                acpiprefs.file_path,
index a0823e94b81255cae72908bca6279959f2b8c37c..446b65215c511813b429319c929dc696ef5c63b2 100644 (file)
@@ -52,6 +52,7 @@
 #include "prefs_common.h"
 #include "alertpanel.h"
 #include "addr_compl.h"
+#include "safe_fclose.h"
 
 #ifdef HAVE_SYSEXITS_H
 #include <sysexits.h>
@@ -279,7 +280,7 @@ static void bogofilter_do_filter(BogoFilterData *data)
                                                                }
                                                        }
                                                        fclose(input);
-                                                       if (fclose(output) == EOF)
+                                                       if (safe_fclose(output) == EOF)
                                                                err = TRUE;
                                                        if (!err)
                                                                move_file(tmpfile, file, TRUE);
index d264aed5825bc8f8138ab6e6706c720ad0103944..a7fa4db5dbccb07ab58c9df385153727b13b8cc7 100644 (file)
@@ -85,6 +85,7 @@ procmsg_msginfo_unset_flags
 procmsg_register_spam_learner
 procmsg_spam_set_folder
 procmsg_unregister_spam_learner
+safe_fclose
 settings
 start_address_completion
 statusbar_pop_all
index 7f5e0f644d25f7a756590422d1b4e0a49e2216f2..1823fd4204335fd94c05b2f877b6943dc341594b 100644 (file)
@@ -28,6 +28,7 @@
 #include <fancy_viewer.h>
 #include <fancy_prefs.h>
 #include <alertpanel.h>
+#include <safe_fclose.h>
 
 #include <printing.h>
 #include <webkit/webkithittestresult.h>
@@ -670,7 +671,7 @@ static void *download_file_curl (void *data)
                if (CURLE_OK != res)
                        alertpanel_error(_("An error occurred: %d\n"), res);
                if (viewer->stream)
-                       fclose(viewer->stream);
+                       safe_fclose(viewer->stream);
                curl_global_cleanup();
        }
 #ifdef USE_PTHREAD
index faf52cc2f5d64f697ba486bffa798d775bee61a7..924b5d1d88e9c0f4fcfa77dfc7a8e6d9d71d6d41 100644 (file)
@@ -36,5 +36,6 @@ prefs_write_param
 prefs_common_get_prefs
 procmsg_msginfo_add_avatar
 procmsg_msginfo_get_avatar
+safe_fclose
 slist_free_strings_full
 to_human_readable
index 02c7e4b342f53c87287c1e659b315c85d8b4d674..66a0e1d7e49e7824104188a788000776b2fcb3eb 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <common/claws.h>
 #include <prefs_common.h>
+#include <safe_fclose.h>
 
 #include "libravatar.h"
 #include "libravatar_prefs.h"
@@ -106,7 +107,7 @@ static GdkPixbuf *pixbuf_from_url(const gchar *url, const gchar *md5, const gcha
        debug_print("retrieving URL to file: %s -> %s\n", url, filename);
        curl_easy_perform(curl);
        filesize = ftell(file);
-       fclose(file);
+       safe_fclose(file);
        if (filesize < MIN_PNG_SIZE)
                debug_print("not enough data for an avatar image: %ld bytes\n", filesize);
        else
index 5ea99a7abc7185e94696e2723524f5bb715a1d73..6a0191185ad2cb94250158cc2d8545866f0d91ae 100644 (file)
@@ -21,6 +21,7 @@
 #include "libravatar_missing.h"
 #include "libravatar_prefs.h"
 #include "utils.h"
+#include "safe_fclose.h"
 
 /**
  * Loads the hash table of md5sum â†’ time from the given filename.
@@ -108,7 +109,7 @@ gint missing_save_to_file(GHashTable *table, const gchar *filename)
        g_hash_table_foreach(table, missing_save_item, (gpointer)file);
        debug_print("Saved %u missing avatar entries\n", g_hash_table_size(table));
 
-       if (fclose(file) != 0) {
+       if (safe_fclose(file) != 0) {
                g_warning("error closing '%s'", filename);
                return -1;
        }
index 5d8ff7528314a8cfe8b84bdcc62dd16f69777b73..0f686d31dc7eeb33f6b4a27da59a12d242228500 100644 (file)
@@ -28,3 +28,4 @@ prefs_set_default
 prefs_write_open
 prefs_write_param
 prefs_common_get_prefs
+safe_fclose
\ No newline at end of file
index 8b601fcf62e7510df54df2de3a998816e8d54fa3..1db007ba35172db7235af4337586a122f9a79976 100644 (file)
@@ -56,6 +56,7 @@
 #include "mailmbox.h"
 #include "mailmbox_folder.h"
 #include "mailmbox_parse.h"
+#include "safe_fclose.h"
 
 #define MAILMBOX_CACHE_DIR           "mailmboxcache"
 
@@ -257,7 +258,7 @@ static void write_max_uid_value(FolderItem *item, guint max_uid)
                 return;
         }
         
-        fclose(f);
+        safe_fclose(f);
 }
 
 static void claws_mailmbox_folder_item_destroy(Folder *folder, FolderItem *_item)
@@ -471,7 +472,7 @@ static gchar *s_claws_mailmbox_fetch_msg(Folder *folder, FolderItem *item, gint
         if (r == 0)
                 goto close;
         
-        fclose(f);
+        safe_fclose(f);
         
        return file;
         
index c9f0ecd18500d027aea4d0b18bb7edd28a430cb4..a07c65f892b4032a71c6833498b4cd5fd66664ea 100644 (file)
@@ -22,3 +22,4 @@ procmime_scan_file
 procmime_write_mimeinfo
 procmime_get_part
 procmime_get_tmp_file_name
+safe_fclose
\ No newline at end of file
index 6ebb8836df3541ad8b3ecd9752799c7d8bc5fa81..bd2f026aa0ed57d22ef7742636ce3a9f1608faba 100644 (file)
@@ -28,6 +28,7 @@
 #include <glib/gi18n.h>
 #include <errno.h>
 #include <gpgme.h>
+#include <safe_fclose.h>
 
 #include "utils.h"
 #include "privacy.h"
@@ -410,7 +411,7 @@ static MimeInfo *pgpinline_decrypt(MimeInfo *mimeinfo)
            }
        }
 
-       if (fclose(dstfp) == EOF) {
+       if (safe_fclose(dstfp) == EOF) {
                FILE_OP_ERROR(fname, "fclose");
                privacy_set_error(_("Couldn't close decrypted file %s"), fname);
                g_free(fname);
index fe03c78794d842bf445772050aab5a876a9179e7..0d01d49e9fa17e8bbb9ccd4f330dba91021a7b2b 100644 (file)
@@ -18,3 +18,4 @@ procmime_mimeinfo_new
 procmime_mimeinfo_parent
 procmime_scan_file
 procmime_write_mimeinfo
+safe_fclose
\ No newline at end of file
index 8dc761d1598d1a503a369524f2adfa30017e1a2d..ff01c9367797cc2abcb08b682eaf1ded03e0364f 100644 (file)
@@ -42,6 +42,7 @@
 #include <plugins/pgpcore/pgp_utils.h>
 
 #include "prefs_common.h"
+#include "safe_fclose.h"
 
 typedef struct _PrivacyDataPGP PrivacyDataPGP;
 
@@ -384,7 +385,7 @@ static MimeInfo *pgpmime_decrypt(MimeInfo *mimeinfo)
        }
        g_free(chars);
 
-       if (fclose(dstfp) == EOF) {
+       if (safe_fclose(dstfp) == EOF) {
                FILE_OP_ERROR(fname, "fclose");
                privacy_set_error(_("Couldn't close decrypted file %s"), fname);
                g_free(fname);
index 5f257e53a214443fb7cee27007ba78125c526c1c..6fc560f824bbef73728bd8d019551ee970b6dcc1 100644 (file)
@@ -116,6 +116,7 @@ procheader_parse_file
 procmsg_get_message_file
 procmsg_msginfo_unset_flags
 remove_dir_recursive
+safe_fclose
 slist_free_strings_full
 strtailchomp
 subst_for_shellsafe_filename
index dfc7c903adfb7cd033d420eb6b765d0047f401ee..884f72cd528e9db56d6ad28c5c3463c74e597cfd 100644 (file)
@@ -32,6 +32,7 @@
 #include <log.h>
 #include <folder.h>
 #include <common/utils.h>
+#include <safe_fclose.h>
 
 /* Local includes */
 #include "libfeed/date.h"
@@ -185,7 +186,7 @@ void rssyl_opml_export(void)
 
        debug_print("RSSyl: Feed export finished.\n");
 
-       fclose(f);
+       safe_fclose(f);
        g_free(opmlfile);
        g_free(ctx);
 }
index 685d75ba8c7ac5448b36b0c4e86a2d97f3e57ca0..048eb04269525b09894a741598050705be1c5ed9 100644 (file)
@@ -34,6 +34,7 @@
 #include <codeconv.h>
 #include <procmsg.h>
 #include <common/utils.h>
+#include <safe_fclose.h>
 
 /* Local includes */
 #include "libfeed/date.h"
@@ -546,7 +547,7 @@ void rssyl_add_item(RFolderItem *ritem, FeedItem *feed_item)
                                feed_item_enclosure_get_size(enc) );
 
        fprintf(f, "</body></html>\n");
-       fclose(f);
+       safe_fclose(f);
 
        g_return_if_fail(template != NULL);
 
index 497ed34deaf21dd9afc14917a2a29647b969b064..f6e6a76b8d1785c3d15c353b0b16eb8f71571531 100644 (file)
@@ -31,6 +31,7 @@
 /* Claws Mail includes */
 #include <codeconv.h>
 #include <common/utils.h>
+#include <safe_fclose.h>
 
 /* Local includes */
 #include "rssyl.h"
@@ -188,7 +189,7 @@ static void rssyl_deleted_store_internal(GSList *deleted_items, const gchar *del
        g_slist_foreach(deleted_items, (GFunc)_store_one_deleted_item,
                        (gpointer)f);
 
-       fclose(f);
+       safe_fclose(f);
        debug_print("RSSyl: written and closed deletion file\n");
 }
 
index eec9eb56c6968845c8f9a126fb312993a1be555d..09f67d1488892ae8dba8ba05162994e9fb2b9588 100644 (file)
@@ -26,4 +26,5 @@ procmime_mimeinfo_parent
 procmime_scan_file
 procmime_write_mime_header
 procmime_write_mimeinfo
+safe_fclose
 str_write_to_file
index 93268a3ea7ef9aedc2f3caa97efc8f29d8caa930..08d8dc2d00d7a34d5a821a2cdccdcc7f5dbbd9e1 100644 (file)
@@ -43,6 +43,7 @@
 #include "prefs_common.h"
 #include "procmime.h"
 #include "plugin.h"
+#include "safe_fclose.h"
 
 typedef struct _PrivacyDataPGP PrivacyDataPGP;
 
@@ -480,7 +481,7 @@ static MimeInfo *smime_decrypt(MimeInfo *mimeinfo)
                        return NULL;
                }
        }
-       if (fclose(dstfp) == EOF) {
+       if (safe_fclose(dstfp) == EOF) {
                FILE_OP_ERROR(fname, "fclose");
                g_free(fname);
                        g_free(chars);
@@ -804,7 +805,7 @@ gboolean smime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
        procmime_decode_content(msgcontent);
        procmime_write_mime_header(msgcontent, fp);
        procmime_write_mimeinfo(msgcontent, fp);
-       fclose(fp);
+       safe_fclose(fp);
        canonicalize_file_replace(tmpfile);
        fp = g_fopen(tmpfile, "rb");
        if (fp == NULL) {
@@ -846,7 +847,7 @@ gboolean smime_encrypt(MimeInfo *mimeinfo, const gchar *encrypt_data)
                        g_free(enccontent);
                        return FALSE;
                }
-               if (fclose(fp) == EOF) {
+               if (safe_fclose(fp) == EOF) {
                        FILE_OP_ERROR(tmpfile, "fclose");
                        claws_unlink(tmpfile);
                        g_free(tmpfile);
index a0add79a23285423894bf115282089997875bac5..f6d4208976cdbcc0a9824ade4fe56500c360859d 100644 (file)
@@ -144,6 +144,7 @@ procmsg_msginfo_get_full_info
 procmsg_send_message_queue_with_lock
 qp_encode_line
 remove_dir_recursive
+safe_fclose
 slist_free_strings
 slist_free_strings_full
 statusbar_progress_all
index 299e033e103f4546856b99db2b51d7488a159275..68d2069cf16988d98e17eba345834fc7c556930b 100644 (file)
@@ -54,6 +54,7 @@
 #include "gtkutils.h"
 #include "log.h"
 #include "utils.h"
+#include "safe_fclose.h"
 
 struct _VCalMeeting
 {
@@ -1872,7 +1873,7 @@ void multisync_export(void)
                                FILE_OP_ERROR(file, "fprintf");
                        g_free(file);
                }
-               if (fclose(fp) == EOF)
+               if (safe_fclose(fp) == EOF)
                        FILE_OP_ERROR(file, "fclose");
        } else {
                FILE_OP_ERROR(file, "fopen");
index e8831a03ea607a65ca771398beb84205174b9050..f89ddc3ea714e3d16bb0863fcf128a42e4665a9c 100644 (file)
--- a/src/pop.c
+++ b/src/pop.c
@@ -40,6 +40,7 @@
 #include "partial_download.h"
 #include "log.h"
 #include "hooks.h"
+#include "safe_fclose.h"
 
 static gint pop3_greeting_recv         (Pop3Session *session,
                                         const gchar *msg);
@@ -705,7 +706,7 @@ gint pop3_write_uidl_list(Pop3Session *session)
                            > 0);
        }
 
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                FILE_OP_ERROR(tmp_path, "fclose");
                fp = NULL;
                goto err_write;
@@ -806,7 +807,7 @@ static gint pop3_write_msg_to_file(const gchar *file, const gchar *data,
                }
        }
 
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                FILE_OP_ERROR(file, "fclose");
                claws_unlink(file);
                return -1;
index 3c74b0581355955354065998c3e7d3cfe61be6ed..e1b9fde92c02ed60abd61982869ea6479b791856 100644 (file)
@@ -61,6 +61,8 @@
 #include "prefswindow.h"
 #include "colorlabel.h"
 #include "passwordstore.h"
+#include "safe_fclose.h"
+
 #ifndef USE_ALT_ADDRBOOK
        #include "addrcustomattr.h"
 #endif
@@ -1399,7 +1401,7 @@ static void prefs_common_save_history_to_dir(const gchar *dirname, const gchar *
                    fputc('\n', fp) != EOF);
        }
 
-       if (fclose(fp) == EOF) {
+       if (safe_fclose(fp) == EOF) {
                FILE_OP_ERROR(tmp_path, "fclose");
                fp = NULL;
                goto out;
@@ -1415,7 +1417,7 @@ static void prefs_common_save_history_to_dir(const gchar *dirname, const gchar *
 
 out:
        if (fp)
-               fclose(fp);
+               safe_fclose(fp);
        g_free(tmp_path);
        g_free(path);
 }
index df05e9b96d6af89b75ce5513fa5456cf4804bbbd..5c776b453547004b995801ae527e2399c525a0a6 100644 (file)
@@ -49,6 +49,7 @@
 #include "timing.h"
 #include "inc.h"
 #include "privacy.h"
+#include "safe_fclose.h"
 
 extern SessionStats session_stats;
 
@@ -1120,7 +1121,7 @@ gint procmsg_remove_special_headers(const gchar *in, const gchar *out)
                        return -1;
                }
        }
-       fclose(outfp);
+       safe_fclose(outfp);
        fclose(fp);
        return 0;
 }
@@ -1705,7 +1706,7 @@ send_mail:
                                        }
                                }
                        }
-                       fclose(tmpfp);
+                       safe_fclose(tmpfp);
 
                        if (newsval == 0) {
                                debug_print("Sending message by news\n");
@@ -2339,14 +2340,14 @@ MsgInfo *procmsg_msginfo_new_from_mimeinfo(MsgInfo *src_msginfo, MimeInfo *mimei
        }
        
        if (fp && procmime_write_mimeinfo(mimeinfo, fp) >= 0) {
-               fclose(fp);
+               safe_fclose(fp);
                fp = NULL;
                tmp_msginfo = procheader_parse_file(
                        tmpfile, flags, 
                        TRUE, FALSE);
        }
        if (fp)
-               fclose(fp);
+               safe_fclose(fp);
 
        if (tmp_msginfo != NULL) {
                if (src_msginfo)
diff --git a/src/safe_fclose.c b/src/safe_fclose.c
new file mode 100644 (file)
index 0000000..bec77fd
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2018 Colin Leroy and the Claws Mail team
+ *
+ * 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 Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#include "claws-features.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "prefs_common.h"
+#include "common/timing.h"
+
+int safe_fclose(FILE *fp)
+{
+       int r;
+       START_TIMING("");
+
+       if (fflush(fp) != 0) {
+               return EOF;
+       }
+       if (prefs_common_get_prefs()->flush_metadata && fsync(fileno(fp)) != 0) {
+               return EOF;
+       }
+
+       r = fclose(fp);
+       END_TIMING();
+
+       return r;
+}
diff --git a/src/safe_fclose.h b/src/safe_fclose.h
new file mode 100644 (file)
index 0000000..f0153a5
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2018 Colin Leroy and the Claws Mail team
+ *
+ * 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 Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __SAFE_FCLOSE_H__
+#define __SAFE_FCLOSE_H__
+
+int safe_fclose(FILE *fp);
+
+#endif