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)
committerColin Leroy <colin@colino.net>
Fri, 5 Oct 2018 21:01:46 +0000 (23:01 +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 9844f30..b19eccd 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 274d4ac..c519eb7 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 8012996..fda0bcd 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 5c4f249..d1fd799 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 286b836..1003d51 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 23bcc22..362cbb9 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 75b61e6..1f71662 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 e68ee64..e0f020a 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 9d53d88..dfd9603 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 3833545..e3ba80c 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 1aa2dc4..6f17c98 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"
@@ -5983,7 +5985,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;
@@ -6276,7 +6278,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);
@@ -10379,7 +10381,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 80279d2..29d0380 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 675576f..7ed6fc8 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 d9c1b49..eba8737 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 b132989..257ae19 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 398dadd..8a0ce23 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 9929a29..ea1138a 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 6a73c63..1e3d048 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
@@ -1060,7 +1062,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 0bf0783..713ce0d 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 edaa092..871c04a 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 7d5fbfa..6c29cfb 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 e0283cc..384393e 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 1f96ea2..f8abb0b 100644 (file)
@@ -47,6 +47,7 @@
 #include "utils.h"
 #include "folder_item_prefs.h"
 #include "gtkcmoptionmenu.h"
+#include "safe_fclose.h"
 
 #define PREFS_BLOCK_NAME "AcpiNotifier"
 #define PLUGIN_NAME _("Acpi Notifier")
@@ -676,7 +677,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 a0823e9..446b652 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 d264aed..a7fa4db 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 7f5e0f6..1823fd4 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 faf52cc..924b5d1 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 02c7e4b..66a0e1d 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 5ea99a7..6a01911 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 5d8ff75..0f686d3 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 8b601fc..1db007b 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 c9f0ecd..a07c65f 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 6ebb883..bd2f026 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 fe03c78..0d01d49 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 8dc761d..ff01c93 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 5f257e5..6fc560f 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 dfc7c90..884f72c 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 685d75b..048eb04 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 497ed34..f6e6a76 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 eec9eb5..09f67d1 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 93268a3..08d8dc2 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 a0add79..f6d4208 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 d0ea92f..c12ece7 100644 (file)
@@ -54,6 +54,7 @@
 #include "gtkutils.h"
 #include "log.h"
 #include "utils.h"
+#include "safe_fclose.h"
 
 struct _VCalMeeting
 {
@@ -1858,7 +1859,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 e8831a0..f89ddc3 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 b479e0f..444d677 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 df05e9b..5c776b4 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