2007-03-30 [colin] 2.8.1cvs69
authorColin Leroy <colin@colino.net>
Fri, 30 Mar 2007 16:29:52 +0000 (16:29 +0000)
committerColin Leroy <colin@colino.net>
Fri, 30 Mar 2007 16:29:52 +0000 (16:29 +0000)
* src/pop.c
* src/prefs_common.c
Fix possible trashing of history and uidl
files on disk full problems

ChangeLog
PATCHSETS
configure.ac
src/pop.c
src/prefs_common.c

index 4329cf3267724cb0bcc35da0e328389a09773496..98d566ec42cae0eddd756cdc8fc8fe67da42c8fd 100644 (file)
--- 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
index 3fef781aa1a804510a0bce4aeab572b950d38b56..1c4263fede717f4756d0dc5a44035e175556f074 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( 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
index 2d67398056f289fc6ad957cada8eb451f34bccd3..3dba4aceeae3744275992f125d921dc3bdd88095 100644 (file)
@@ -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=
 
index 1333d068595f580f02c6daadf073cec5ecb7f71c..370e6b6a5b2bd8827b8545ba72c93ffd867b93b4 100644 (file)
--- 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)
 {
index 0d8062a54308d8bc1fac282b9b129934bf4fab38..f70e489fab148faf94d807f743001537fc766cce 100644 (file)
@@ -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);