diff options
-rw-r--r-- | camel/ChangeLog | 20 | ||||
-rw-r--r-- | camel/camel-folder-summary.c | 71 | ||||
-rw-r--r-- | camel/providers/local/camel-local-summary.c | 8 | ||||
-rw-r--r-- | camel/providers/local/camel-local-summary.h | 6 |
4 files changed, 63 insertions, 42 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index cf810f8551..198d071934 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,5 +1,25 @@ 2002-09-10 Jeffrey Stedfast <fejj@ximian.com> + * camel-folder-summary.c (perform_content_info_save): Do proper + error checking and return -1 on fail. + (camel_folder_summary_save): Check the return of + perform_content_info_save and a few other output calls within the + message_info_save loop. If any of them fail, save errno, close the + file, and return -1. If we finish the loop without fail, fflush + the stream and then fsync (fflush only flushes user-space buffers, + you still need to fsync afterward to flush the data to disk). If + either fail, treat it as an exception by saving errno, closing the + stream, and returning -1. I suspect that this also fixes bug + #30150 because the old code would fclose if fflush or fclose + failed in the check after the loop (man fclose(3) states that any + further calls using the stream (even another call to fclose) will + have undefined behaviour no matter what the first fclose call + returned). + + * providers/local/camel-local-summary.c + (camel_local_summary_init): Don't malloc a private struct of 0 + size. + * providers/imap/camel-imap-folder.c (camel_imap_folder_fetch_data): Clear the exception even if we failed to get the message (part) from the imap-message-cache if we diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c index ebef730c70..3ec6c93107 100644 --- a/camel/camel-folder-summary.c +++ b/camel/camel-folder-summary.c @@ -602,13 +602,19 @@ perform_content_info_save(CamelFolderSummary *s, FILE *out, CamelMessageContentI { CamelMessageContentInfo *part; - ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_save(s, out, ci); - camel_file_util_encode_uint32(out, my_list_size((struct _node **)&ci->childs)); + if (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->content_info_save (s, out, ci) == -1) + return -1; + + if (camel_file_util_encode_uint32 (out, my_list_size ((struct _node **)&ci->childs)) == -1) + return -1; + part = ci->childs; while (part) { - perform_content_info_save(s, out, part); + if (perform_content_info_save (s, out, part) == -1) + return -1; part = part->next; } + return 0; } @@ -625,8 +631,7 @@ int camel_folder_summary_save(CamelFolderSummary *s) { FILE *out; - int fd; - int i; + int fd, i; guint32 count; CamelMessageInfo *mi; char *path; @@ -641,7 +646,7 @@ camel_folder_summary_save(CamelFolderSummary *s) if (fd == -1) return -1; out = fdopen(fd, "w"); - if ( out == NULL ) { + if (out == NULL) { i = errno; unlink(path); close(fd); @@ -653,46 +658,52 @@ camel_folder_summary_save(CamelFolderSummary *s) CAMEL_SUMMARY_LOCK(s, io_lock); - if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_save(s, out) == -1) { - i = errno; - fclose(out); - CAMEL_SUMMARY_UNLOCK(s, io_lock); - unlink(path); - errno = i; - return -1; - } - + if (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_save(s, out) == -1) + goto exception; + /* now write out each message ... */ /* we check ferorr when done for i/o errors */ - count = s->messages->len; - for (i=0;i<count;i++) { + for (i = 0; i < count; i++) { mi = s->messages->pdata[i]; - ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_save(s, out, mi); - + if (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->message_info_save (s, out, mi) == -1) + goto exception; + if (s->build_content) { - perform_content_info_save(s, out, mi->content); + if (perform_content_info_save (s, out, mi->content) == -1) + goto exception; } } - + + if (fflush (out) != 0 || fsync (fileno (out)) == -1) + goto exception; + + fclose (out); + CAMEL_SUMMARY_UNLOCK(s, io_lock); - - if (ferror(out) != 0 || fclose(out) != 0) { - i = errno; - unlink(path); - errno = i; - return -1; - } - + if (rename(path, s->summary_path) == -1) { i = errno; unlink(path); errno = i; return -1; } - + s->flags &= ~CAMEL_SUMMARY_DIRTY; return 0; + + exception: + + i = errno; + + fclose (out); + + CAMEL_SUMMARY_UNLOCK(s, io_lock); + + unlink (path); + errno = i; + + return -1; } /** diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c index e1007223a0..18c0b80ce5 100644 --- a/camel/providers/local/camel-local-summary.c +++ b/camel/providers/local/camel-local-summary.c @@ -41,11 +41,6 @@ #define CAMEL_LOCAL_SUMMARY_VERSION (0x200) -struct _CamelLocalSummaryPrivate { -}; - -#define _PRIVATE(o) (((CamelLocalSummary *)(o))->priv) - static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _header_raw *); static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi); @@ -100,11 +95,8 @@ camel_local_summary_class_init(CamelLocalSummaryClass *klass) static void camel_local_summary_init(CamelLocalSummary *obj) { - struct _CamelLocalSummaryPrivate *p; struct _CamelFolderSummary *s = (CamelFolderSummary *)obj; - p = _PRIVATE(obj) = g_malloc0(sizeof(*p)); - /* subclasses need to set the right instance data sizes */ s->message_info_size = sizeof(CamelMessageInfo); s->content_info_size = sizeof(CamelMessageContentInfo); diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h index fafa992163..0995331ab1 100644 --- a/camel/providers/local/camel-local-summary.h +++ b/camel/providers/local/camel-local-summary.h @@ -42,11 +42,9 @@ enum { struct _CamelLocalSummary { CamelFolderSummary parent; - - struct _CamelLocalSummaryPrivate *priv; - + char *folder_path; /* name of matching folder */ - + CamelIndex *index; unsigned int index_force:1; /* do we force index during creation? */ unsigned int check_force:1; /* does a check force a full check? */ |