From: Thomas Roessler Date: Thu, 8 Jun 2000 21:44:14 +0000 (+0000) Subject: This patch should fix the mailbox corruption various people observed. X-Git-Tag: mutt-1-3-3-rel~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a947c0a1fb8557f4eea86b27367d131da23ba728;p=mutt This patch should fix the mailbox corruption various people observed. --- diff --git a/copy.c b/copy.c index 6f7e22b3..5ae716c1 100644 --- a/copy.c +++ b/copy.c @@ -297,6 +297,10 @@ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix) rfc822_cat(buffer, sizeof(buffer), Charset, MimeSpecials); fputs(buffer, out); fputc('\n', out); + + if (ferror (out) != 0 || feof (out) != 0) + return -1; + } if (flags & CH_UPDATE) @@ -362,6 +366,9 @@ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix) return (-1); } + if (ferror (out) || feof (out)) + return -1; + return (0); } @@ -453,7 +460,7 @@ _mutt_copy_message (FILE *fpout, FILE *fpin, HEADER *hdr, BODY *body, new_lines = 0; else fprintf (fpout, "Lines: %d\n\n", new_lines); - if (ferror (fpout)) + if (ferror (fpout) || feof (fpout)) return -1; new_offset = ftell (fpout); @@ -583,7 +590,12 @@ mutt_copy_message (FILE *fpout, CONTEXT *src, HEADER *hdr, int flags, if ((msg = mx_open_message (src, hdr->msgno)) == NULL) return -1; - r = _mutt_copy_message (fpout, msg->fp, hdr, hdr->content, flags, chflags); + if ((r = _mutt_copy_message (fpout, msg->fp, hdr, hdr->content, flags, chflags)) == 0 + && (ferror (fpout) || feof (fpout))) + { + dprint (1, (debugfile, "_mutt_copy_message failed to detect EOF!\n")); + r = -1; + } mx_close_message (&msg); return r; } diff --git a/mbox.c b/mbox.c index 6897874b..897e1bd6 100644 --- a/mbox.c +++ b/mbox.c @@ -40,8 +40,11 @@ /* struct used by mutt_sync_mailbox() to store new offsets */ struct m_update_t { + short valid; long hdr; long body; + long lines; + long length; }; /* parameters: @@ -669,11 +672,12 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) int i, j, save_sort = SORT_ORDER; int rc = -1; int need_sort = 0; /* flag to resort mailbox if new mail arrives */ - int first; /* first message to be written */ + int first = -1; /* first message to be written */ long offset; /* location in mailbox to write changed messages */ struct stat statbuf; struct utimbuf utimebuf; struct m_update_t *newOffset = NULL; + struct m_update_t *oldOffset = NULL; FILE *fp = NULL; /* sort message by their position in the mailbox on disk */ @@ -729,6 +733,7 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) unlink (tempfile); } mutt_error _("Could not create temporary file!"); + sleep (5); goto bail; } @@ -766,6 +771,7 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) /* allocate space for the new offsets */ newOffset = safe_calloc (ctx->msgcount - first, sizeof (struct m_update_t)); + oldOffset = safe_calloc (ctx->msgcount - first, sizeof (struct m_update_t)); for (i = first, j = 0; i < ctx->msgcount; i++) { @@ -780,6 +786,8 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) { if (fputs (MMDF_SEP, fp) == EOF) { + mutt_perror (tempfile); + sleep (5); unlink (tempfile); goto bail; } @@ -789,11 +797,24 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) { if (fputs (KENDRA_SEP, fp) == EOF) { + mutt_perror (tempfile); + sleep (5); unlink (tempfile); goto bail; } } + /* + * back up some information which is needed to restore offsets when + * something fails. + */ + + oldOffset[i-first].valid = 1; + oldOffset[i-first].hdr = ctx->hdrs[i]->offset; + oldOffset[i-first].body = ctx->hdrs[i]->content->offset; + oldOffset[i-first].lines = ctx->hdrs[i]->lines; + oldOffset[i-first].length = ctx->hdrs[i]->content->length; + /* save the new offset for this message. we add `offset' because the * temporary file only contains saved message which are located after * `offset' in the real mailbox @@ -802,6 +823,8 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) if (mutt_copy_message (fp, ctx, ctx->hdrs[i], M_CM_UPDATE, CH_FROM | CH_UPDATE | CH_UPDATE_LEN) == -1) { + mutt_perror (tempfile); + sleep (5); unlink (tempfile); goto bail; } @@ -820,6 +843,8 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) case M_MMDF: if(fputs(MMDF_SEP, fp) == EOF) { + mutt_perror (tempfile); + sleep (5); unlink (tempfile); goto bail; } @@ -827,6 +852,8 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) case M_KENDRA: if(fputs(KENDRA_SEP, fp) == EOF) { + mutt_perror (tempfile); + sleep (5); unlink (tempfile); goto bail; } @@ -834,6 +861,8 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) default: if(fputs("\n", fp) == EOF) { + mutt_perror (tempfile); + sleep (5); unlink (tempfile); goto bail; } @@ -855,6 +884,8 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) /* Save the state of this folder. */ if (stat (ctx->path, &statbuf) == -1) { + mutt_perror (ctx->path); + sleep (5); unlink (tempfile); goto bail; } @@ -955,6 +986,7 @@ int mbox_sync_mailbox (CONTEXT *ctx, int *index_hint) } } safe_free ((void **) &newOffset); + safe_free ((void **) &oldOffset); unlink (tempfile); /* remove partial copy of the mailbox */ mutt_unblock_signals (); Sort = save_sort; /* Restore the default value. */ @@ -965,11 +997,25 @@ bail: /* Come here in case of disaster */ safe_fclose (&fp); + /* restore offsets, as far as they are valid */ + if (first >= 0 && oldOffset) + { + for (i = first; i < ctx->msgcount && oldOffset[i-first].valid; i++) + { + ctx->hdrs[i]->offset = oldOffset[i-first].hdr; + ctx->hdrs[i]->content->hdr_offset = oldOffset[i-first].hdr; + ctx->hdrs[i]->content->offset = oldOffset[i-first].body; + ctx->hdrs[i]->lines = oldOffset[i-first].lines; + ctx->hdrs[i]->content->length = oldOffset[i-first].length; + } + } + /* this is ok to call even if we haven't locked anything */ mbox_unlock_mailbox (ctx); mutt_unblock_signals (); safe_free ((void **) &newOffset); + safe_free ((void **) &oldOffset); if ((ctx->fp = freopen (ctx->path, "r", ctx->fp)) == NULL) {