From 41ca5d368b4e712f43eaa4d96a8d0ffcab7d5ca6 Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Fri, 30 Mar 2007 16:29:52 +0000 Subject: [PATCH 1/1] 2007-03-30 [colin] 2.8.1cvs69 * src/pop.c * src/prefs_common.c Fix possible trashing of history and uidl files on disk full problems --- ChangeLog | 7 +++++++ PATCHSETS | 1 + configure.ac | 2 +- src/pop.c | 50 ++++++++++++++++++++++++++++++++++++---------- src/prefs_common.c | 43 +++++++++++++++++++++++++++++++-------- 5 files changed, 84 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4329cf326..98d566ec4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-03-30 [colin] 2.8.1cvs69 + + * src/pop.c + * src/prefs_common.c + Fix possible trashing of history and uidl + files on disk full problems + 2007-03-30 [paul] 2.8.1cvs68 * src/mainwindow.c diff --git a/PATCHSETS b/PATCHSETS index 3fef781aa..1c4263fed 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -2485,3 +2485,4 @@ ( cvs diff -u -r 1.382.2.367 -r 1.382.2.368 src/compose.c; cvs diff -u -r 1.50.2.33 -r 1.50.2.34 src/compose.h; cvs diff -u -r 1.204.2.126 -r 1.204.2.127 src/prefs_common.c; cvs diff -u -r 1.13.2.29 -r 1.13.2.30 src/common/socket.c; cvs diff -u -r 1.13.2.13 -r 1.13.2.14 src/common/socket.h; ) > 2.8.1cvs66.patchset ( cvs diff -u -r 1.3.2.14 -r 1.3.2.15 src/prefs_ext_prog.c; ) > 2.8.1cvs67.patchset ( cvs diff -u -r 1.274.2.182 -r 1.274.2.183 src/mainwindow.c; cvs diff -u -r 1.395.2.293 -r 1.395.2.294 src/summaryview.c; cvs diff -u -r 1.68.2.35 -r 1.68.2.36 src/summaryview.h; ) > 2.8.1cvs68.patchset +( cvs diff -u -r 1.56.2.48 -r 1.56.2.49 src/pop.c; cvs diff -u -r 1.204.2.127 -r 1.204.2.128 src/prefs_common.c; ) > 2.8.1cvs69.patchset diff --git a/configure.ac b/configure.ac index 2d6739805..3dba4acee 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=8 MICRO_VERSION=1 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=68 +EXTRA_VERSION=69 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/pop.c b/src/pop.c index 1333d0685..370e6b6a5 100644 --- a/src/pop.c +++ b/src/pop.c @@ -633,9 +633,16 @@ void pop3_get_uidl_table(PrefsAccount *ac_prefs, Pop3Session *session) return; } +#define TRY(func) \ +if (!(func)) \ +{ \ + g_warning("failed to write\n"); \ + goto err_write; \ +} \ + gint pop3_write_uidl_list(Pop3Session *session) { - gchar *path; + gchar *path, *tmp_path; FILE *fp; Pop3MsgInfo *msg; gint n; @@ -650,29 +657,52 @@ gint pop3_write_uidl_list(Pop3Session *session) "uidl", G_DIR_SEPARATOR_S, session->ac_prefs->recv_server, "-", sanitized_uid, NULL); - + tmp_path = g_strconcat(path, ".tmp", NULL); + g_free(sanitized_uid); - if ((fp = g_fopen(path, "wb")) == NULL) { - FILE_OP_ERROR(path, "fopen"); - g_free(path); - return -1; + if ((fp = g_fopen(tmp_path, "wb")) == NULL) { + FILE_OP_ERROR(tmp_path, "fopen"); + goto err_write; } for (n = 1; n <= session->count; n++) { msg = &session->msg[n]; if (msg->uidl && msg->received && (!msg->deleted || session->state != POP3_DONE)) - fprintf(fp, "%s\t%ld\t%d\n", - msg->uidl, (long int) msg->recv_time, msg->partial_recv); + TRY(fprintf(fp, "%s\t%ld\t%d\n", + msg->uidl, (long int) + msg->recv_time, + msg->partial_recv) + > 0); } - if (fclose(fp) == EOF) FILE_OP_ERROR(path, "fclose"); + if (fclose(fp) == EOF) { + FILE_OP_ERROR(tmp_path, "fclose"); + fp = NULL; + goto err_write; + } + fp = NULL; +#ifdef G_OS_WIN32 + g_unlink(path); +#endif + if (g_rename(tmp_path, path) < 0) { + FILE_OP_ERROR(path, "rename"); + goto err_write; + } g_free(path); - + g_free(tmp_path); return 0; +err_write: + if (fp) + fclose(fp); + g_free(path); + g_free(tmp_path); + return -1; } +#undef TRY + static gint pop3_write_msg_to_file(const gchar *file, const gchar *data, guint len, const gchar *prefix) { diff --git a/src/prefs_common.c b/src/prefs_common.c index 0d8062a54..f70e489fa 100644 --- a/src/prefs_common.c +++ b/src/prefs_common.c @@ -1064,6 +1064,13 @@ void prefs_common_read_config(void) colorlabel_update_colortable_from_prefs(); } +#define TRY(func) \ +if (!(func)) \ +{ \ + g_warning("failed to write\n"); \ + goto out; \ +} \ + /* * Save history list to the specified history file */ @@ -1071,25 +1078,45 @@ static void prefs_common_save_history(const gchar *history, GList *list) { GList *cur; FILE *fp; - gchar *path; + gchar *path, *tmp_path; path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, history, NULL); - if ((fp = g_fopen(path, "wb")) == NULL) { - FILE_OP_ERROR(path, "fopen"); - g_free(path); - return; + tmp_path = g_strconcat(path, ".tmp", NULL); + + if ((fp = g_fopen(tmp_path, "wb")) == NULL) { + FILE_OP_ERROR(tmp_path, "fopen"); + goto out; } for (cur = list; cur != NULL; cur = cur->next) { - fputs((gchar *)cur->data, fp); - fputc('\n', fp); + TRY(fputs((gchar *)cur->data, fp) != EOF && + fputc('\n', fp) != EOF); } - fclose(fp); + if (fclose(fp) == EOF) { + FILE_OP_ERROR(tmp_path, "fclose"); + fp = NULL; + goto out; + } + fp = NULL; +#ifdef G_OS_WIN32 + g_unlink(path); +#endif + if (g_rename(tmp_path, path) < 0) { + FILE_OP_ERROR(path, "rename"); + goto out; + } + +out: + if (fp) + fclose(fp); + g_free(tmp_path); g_free(path); } +#undef TRY + void prefs_common_write_config(void) { prefs_write_config(param, "Common", COMMON_RC); -- 2.25.1