Commit Diff


commit - dab376b8b67c043a8a5e937abc4452cdd533eaac
commit + 30d1a28ae115c9aa91c308768e9e392fd71b481c
blob - fef764efd2e28a97e0d71869a8065f397116552b
blob + a0c9137c6fb86eac769c6cfc9fe43b9d5377c5a4
--- README.md
+++ README.md
@@ -45,6 +45,7 @@ To run the app:
 ## Goals
 
 Many features of Claws Mail have been removed to make it easier to maintain by a single person.
+As of the end of 2025, Talons is less than half the size of Claws Mail; 120KLOC. versus Claws Mail 4.3.1 at around 295KLOC.
 
 To be honest I can't even remember how many or which features have been removed.
 Off the top of my head:
@@ -55,6 +56,7 @@ Off the top of my head:
 - no localisation (sorry)
 - no actions
 - no client-side mail filtering
+- no LDAP, Palm Pilot address books
 
 [Zig]: https://ziglang.org
 [Claws Mail]: https://claws-mail.org
blob - b92cddf2a4f4ab23b4128a75ae9eb73afa3ab9e2
blob + ad2cea13b4e15ca1b56cb44e4ed26af80929e902
--- src/addrbook.c
+++ src/addrbook.c
@@ -1328,7 +1328,7 @@ static gint addrbook_write_to(AddressBookFile *book, g
 
 		book->retVal = MGU_SUCCESS;
 #ifdef DEV_STANDALONE
-		safe_fclose(fp);
+		fclose(fp);
 #else
 		if (prefs_file_close( pfile ) < 0)
 			book->retVal = MGU_ERROR_WRITE;
blob - d8a6047e6068a06e30f7de04444c00d4e4fa0eea
blob + 45696c111fc8bd8b0e7013a82bfd6a681838d355
--- src/addrindex.c
+++ src/addrindex.c
@@ -1051,13 +1051,8 @@ static gint addrindex_write_to( AddressIndex *addrInde
 			goto fail;
 
 		addrIndex->retVal = MGU_SUCCESS;
-#ifdef DEV_STANDALONE
-		safe_fclose( fp );
-#else
-		if( prefs_file_close( pfile ) < 0 ) {
+		if (prefs_file_close(pfile) < 0)
 			addrIndex->retVal = MGU_ERROR_WRITE;
-		}
-#endif
 	}
 
 	fileSpec = NULL;
blob - ec93821554b472b10cf6ac6579de6fd7ae9afdaa
blob + 1c51fec62c0b194f3e19a2e15eed3d7d52edb132
--- src/common/file-utils.c
+++ src/common/file-utils.c
@@ -20,6 +20,7 @@
 
 #include <sys/wait.h>
 
+#include <err.h>
 #include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -30,17 +31,6 @@
 #include "utils.h"
 #include "file-utils.h"
 
-int safe_fclose(FILE *fp)
-{
-	if (fflush(fp) != 0) {
-		return EOF;
-	}
-	if (fsync(fileno(fp)) != 0) {
-		return EOF;
-	}
-	return fclose(fp);
-}
-
 gint file_strip_crs(const gchar *file)
 {
 	FILE *fp = NULL, *outfp = NULL;
@@ -69,7 +59,7 @@ gint file_strip_crs(const gchar *file)
 	}
 
 	fclose(fp);
-	if (safe_fclose(outfp) == EOF) {
+	if (fclose(outfp) == EOF) {
 		goto unlinkout;
 	}
 
@@ -204,7 +194,7 @@ gint copy_file(const gchar *src, const gchar *dest, gb
 		err = TRUE;
 	}
 	fclose(src_fp);
-	if (safe_fclose(dest_fp) == EOF) {
+	if (fclose(dest_fp) == EOF) {
 		FILE_OP_ERROR(dest, "fclose");
 		err = TRUE;
 	}
@@ -302,7 +292,7 @@ gint copy_file_part(FILE *fp, off_t offset, size_t len
 	if (copy_file_part_to_fp(fp, offset, length, dest_fp) < 0)
 		err = TRUE;
 
-	if (safe_fclose(dest_fp) == EOF) {
+	if (fclose(dest_fp) == EOF) {
 		FILE_OP_ERROR(dest, "fclose");
 		err = TRUE;
 	}
@@ -384,7 +374,7 @@ gint canonicalize_file(const gchar *src, const gchar *
 		err = TRUE;
 	}
 	fclose(src_fp);
-	if (safe_fclose(dest_fp) == EOF) {
+	if (fclose(dest_fp) == EOF) {
 		FILE_OP_ERROR(dest, "fclose");
 		err = TRUE;
 	}
@@ -420,45 +410,31 @@ gint canonicalize_file_replace(const gchar *file)
 }
 
 
-gint str_write_to_file(const gchar *str, const gchar *file, gboolean safe)
+gint str_write_to_file(const gchar *str, char *file)
 {
-	FILE *fp;
-	size_t len;
-	int r;
-
-	cm_return_val_if_fail(str != NULL, -1);
-	cm_return_val_if_fail(file != NULL, -1);
-
-	if ((fp = g_fopen(file, "wb")) == NULL) {
-		FILE_OP_ERROR(file, "g_fopen");
-		return -1;
-	}
-
-	len = strlen(str);
-	if (len == 0) {
-		fclose(fp);
+	if (strlen(str) == 0)
 		return 0;
+
+	FILE *fp = fopen(file, "wb");
+	if (fp == NULL) {
+		warn("open %s", file);
+		return -1;
 	}
 
-	if (fwrite(str, 1, len, fp) != len) {
-		FILE_OP_ERROR(file, "fwrite");
+	size_t len = strlen(str);
+	size_t n = fwrite(str, 1, strlen(str), fp);
+	if (n != len) {
+		warn("short write to %s: expected %d bytes but wrote %d", file, len, n);
 		fclose(fp);
-		unlink(file);
+		remove(file);
 		return -1;
 	}
 
-	if (safe) {
-		r = safe_fclose(fp);
-	} else {
-		r = fclose(fp);
-	}
-
-	if (r == EOF) {
-		FILE_OP_ERROR(file, "fclose");
-		unlink(file);
+	if (fclose(fp) == EOF) {
+		warn("close %s", file);
+		remove(file);
 		return -1;
 	}
-
 	return 0;
 }
 
blob - a1a180d3ecd0de5c14dd386047970f9142a7fbf4
blob + 7415f849ff040114ad012afab9c343361d9c84f7
--- src/common/file-utils.h
+++ src/common/file-utils.h
@@ -22,8 +22,6 @@
 #include <stdio.h>
 #include <glib.h>
 
-int safe_fclose(FILE *fp);
-
 gint file_strip_crs		(const gchar	*file);
 gint append_file		(const gchar	*src,
 				 const gchar	*dest,
@@ -60,9 +58,7 @@ FILE *my_tmpfile		(void);
 FILE *get_tmpfile_in_dir	(const gchar 	*dir,
 				 gchar	       **filename);
 FILE *str_open_as_stream	(const gchar	*str);
-gint str_write_to_file		(const gchar	*str,
-				 const gchar	*file,
-				 gboolean	 safe);
+gint str_write_to_file		(const gchar *str, char *file);
 
 gint prefs_chmod_mode		(gchar *chmod_pref);
 
blob - a9693e2fd6d59568343ab983d0102efcc3ae2788
blob + 06f3b712bcdb551dc96c7c9529b95d5662710531
--- src/common/prefs.c
+++ src/common/prefs.c
@@ -155,7 +155,7 @@ gint prefs_file_close(PrefFile *pfile)
 
 	tmppath = g_strconcat(path, ".tmp", NULL);
 
-	if (safe_fclose(fp) == EOF) {
+	if (fclose(fp) == EOF) {
 		FILE_OP_ERROR(tmppath, "fclose");
 		unlink(tmppath);
 		g_free(path);
blob - 3daf7a4df9e4e454658eeda47e8c341a3d6a0bdf
blob + a74762ffa52c911c0e5863f74aca8758d7a4f31b
--- src/common/ssl_certificate.c
+++ src/common/ssl_certificate.c
@@ -371,7 +371,7 @@ static void ssl_certificate_save (SSLCertificate *cert
 	gnutls_export_X509_fp(fp, cert->x509_cert, GNUTLS_X509_FMT_DER);
 
 	g_free(file);
-	safe_fclose(fp);
+	fclose(fp);
 
 }
 
@@ -676,7 +676,7 @@ static void ssl_certificate_save_chain(gnutls_x509_crt
 
 	}
 	if (fp)
-		safe_fclose(fp);
+		fclose(fp);
 }
 
 gboolean ssl_certificate_check (gnutls_x509_crt_t x509_cert, guint status,
blob - faad4fd71fab6822cc953363bf01d27ac70781f6
blob + de62e33401dca583a41b80309db4b0ddc94d6b4c
--- src/common/utils.c
+++ src/common/utils.c
@@ -3499,7 +3499,7 @@ void mailcap_update_default(const gchar *type, const g
 	if (fp)
 		fclose(fp);
 
-	if (safe_fclose(outfp) == EOF)
+	if (fclose(outfp) == EOF)
 		err = TRUE;
 
 	if (!err)
blob - 28567290bd0264bd4f8fdb8535f84e460ef3c403
blob + 676a1274f89652e6fe4190634cd4eb15f65b9e4b
--- src/compose.c
+++ src/compose.c
@@ -4936,7 +4936,7 @@ static gint compose_write_to_file(Compose *compose, FI
 					rewind(fp);
 					content = file_read_stream_to_str(fp);
 
-					str_write_to_file(content, tmp_enc_file, TRUE);
+					str_write_to_file(content, tmp_enc_file);
 					g_free(content);
 
 					/* Now write the unencrypted body. */
@@ -5021,7 +5021,7 @@ static gint compose_write_body_to_file(Compose *compos
 
 	g_free(chars);
 
-	if (safe_fclose(fp) == EOF) {
+	if (fclose(fp) == EOF) {
 		FILE_OP_ERROR(file, "fclose");
 		unlink(file);
 		return -1;
@@ -5286,7 +5286,7 @@ static ComposeQueueResult compose_queue_sub(Compose *c
 		g_free(tmp);
 		return COMPOSE_QUEUE_ERROR_WITH_ERRNO;
 	}
-	if (safe_fclose(fp) == EOF) {
+	if (fclose(fp) == EOF) {
 		FILE_OP_ERROR(tmp, "fclose");
 		unlink(tmp);
 		g_free(tmp);
@@ -8448,7 +8448,7 @@ gboolean compose_draft (gpointer data, guint action)
 		fclose(fp);
 		goto warn_err;
 	}
-	if (safe_fclose(fp) == EOF) {
+	if (fclose(fp) == EOF) {
 		goto warn_err;
 	}
 
@@ -8948,7 +8948,7 @@ int attach_image(Compose *compose, GtkSelectionData *d
 		return -1;
 	}
 
-	r = safe_fclose(fp);
+	r = fclose(fp);
 
 	if (r == EOF) {
 		FILE_OP_ERROR(file, "fclose");
@@ -9625,7 +9625,7 @@ static void compose_insert_drag_received_cb (GtkWidget
 			/* Assume a list of no files, and data has ://, is a remote link */
 			gchar *tmpdata = g_strstrip(g_strdup(ddata));
 			gchar *tmpfile = get_tmp_file();
-			str_write_to_file(tmpdata, tmpfile, TRUE);
+			str_write_to_file(tmpdata, tmpfile);
 			g_free(tmpdata);
 			compose_insert_file(compose, tmpfile);
 			unlink(tmpfile);
blob - a6f33bc49d03910d5620491f6df35516239cace8
blob + da387a52a94ecd67501dec829bbe66c4fe653012
--- src/etpan/imap-thread.c
+++ src/etpan/imap-thread.c
@@ -2532,7 +2532,7 @@ static void fetch_content_run(struct etpan_thread_op *
 			goto do_fclose;
 		}
 
-		if (safe_fclose(f) == EOF) {
+		if (fclose(f) == EOF) {
 			result->error = MAILIMAP_ERROR_FETCH;
 			goto unlink;
 		}
blob - 806f21a382a843585323ca334db8999eeee6ad72
blob + 7c68ad3202506f2f71f94a739a644262aad6cf40
--- src/mbox.c
+++ src/mbox.c
@@ -202,7 +202,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, Pr
 			return -1;
 		}
 
-		if (safe_fclose(tmp_fp) == EOF) {
+		if (fclose(tmp_fp) == EOF) {
 			FILE_OP_ERROR(tmp_file, "fclose");
 			g_warning("can't write to temporary file");
 			fclose(mbox_fp);
@@ -284,7 +284,7 @@ gint copy_mbox(gint srcfd, const gchar *dest)
 		err = TRUE;
 	}
 
-	if (safe_fclose(dest_fp) == EOF) {
+	if (fclose(dest_fp) == EOF) {
 		FILE_OP_ERROR(dest, "fclose");
 		err = TRUE;
 	}
@@ -395,7 +395,7 @@ gint export_list_to_mbox(GSList *mlist, const gchar *m
 			goto out;
 		}
 
-		safe_fclose(msg_fp);
+		fclose(msg_fp);
 		statusbar_progress_all(msgs++,total, 500);
 		if (msgs%500 == 0)
 			GTK_EVENTS_FLUSH();
@@ -405,7 +405,7 @@ out:
 	statusbar_progress_all(0,0,0);
 	statusbar_pop_all();
 
-	safe_fclose(mbox_fp);
+	fclose(mbox_fp);
 
 	return err;
 }
blob - 79982edc69e887df01ea7f2d70c29039b5edadc7
blob + f9651f836508fa3073f32715e70cbc9834c6322d
--- src/msgcache.c
+++ src/msgcache.c
@@ -975,9 +975,9 @@ gint msgcache_write(const gchar *cache_file, const gch
 
 	/* close files */
 	if (write_fps.cache_fp)
-		write_fps.error |= (safe_fclose(write_fps.cache_fp) != 0);
+		write_fps.error |= (fclose(write_fps.cache_fp) != 0);
 	if (write_fps.mark_fp)
-		write_fps.error |= (safe_fclose(write_fps.mark_fp) != 0);
+		write_fps.error |= (fclose(write_fps.mark_fp) != 0);
 
 	if (write_fps.error != 0) {
 		/* in case of error, forget all */
blob - 2361a57f7dafb1d85d3f648f0349441697f72cab
blob + 0a7786e1812fed0b88c24e683e9f81f5a97ba438
--- src/pop.c
+++ src/pop.c
@@ -631,7 +631,7 @@ gint pop3_write_uidl_list(Pop3Session *session)
 			    > 0);
 	}
 
-	if (safe_fclose(fp) == EOF) {
+	if (fclose(fp) == EOF) {
 		FILE_OP_ERROR(tmp_path, "fclose");
 		fp = NULL;
 		goto err_write;
@@ -729,7 +729,7 @@ static gint pop3_write_msg_to_file(const gchar *file, 
 		}
 	}
 
-	if (safe_fclose(fp) == EOF) {
+	if (fclose(fp) == EOF) {
 		FILE_OP_ERROR(file, "fclose");
 		unlink(file);
 		return -1;
blob - 152f0f4c9a009d3f22c7425a1d68751eb6e533e4
blob + 2378da0af60415b9fb279cf6bdede0697d0db9a6
--- src/prefs_account.c
+++ src/prefs_account.c
@@ -3442,7 +3442,7 @@ static void prefs_account_signature_edit_cb(GtkWidget 
 {
 	const gchar *sigpath = gtk_entry_get_text(GTK_ENTRY(data));
 	if (!is_file_exist(sigpath))
-		str_write_to_file(sigpath, "", TRUE);
+		str_write_to_file(sigpath, "");
 	open_txt_editor(sigpath, prefs_common_get_ext_editor_cmd());
 }
 
blob - c4df5b30783b4811f3fe4fe70b8d0471199343a2
blob + b77bbd6d5366a3aa6554739e6b20f0265aba62e2
--- src/prefs_common.c
+++ src/prefs_common.c
@@ -1018,7 +1018,7 @@ static void prefs_common_save_history_to_dir(const gch
 		    fputc('\n', fp) != EOF);
 	}
 
-	if (safe_fclose(fp) == EOF) {
+	if (fclose(fp) == EOF) {
 		FILE_OP_ERROR(tmp_path, "fclose");
 		fp = NULL;
 		goto out;
@@ -1031,7 +1031,7 @@ static void prefs_common_save_history_to_dir(const gch
 
 out:
 	if (fp)
-		safe_fclose(fp);
+		fclose(fp);
 	g_free(tmp_path);
 	g_free(path);
 }
blob - 40cb0d741828c3de2c95021b26669e0743ee0c05
blob + 663f1dd2a2fb3fbaef5a67588f74bea5734ad191
--- src/procmsg.c
+++ src/procmsg.c
@@ -1998,14 +1998,14 @@ MsgInfo *procmsg_msginfo_new_from_mimeinfo(MsgInfo *sr
 	}
 
 	if (fp && procmime_write_mimeinfo(mimeinfo, fp) >= 0) {
-		safe_fclose(fp);
+		fclose(fp);
 		fp = NULL;
 		tmp_msginfo = procheader_parse_file(
 			tmpfile, flags,
 			TRUE, FALSE);
 	}
 	if (fp)
-		safe_fclose(fp);
+		fclose(fp);
 
 	if (tmp_msginfo != NULL) {
 		if (src_msginfo)