aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog20
-rw-r--r--camel/camel-folder-summary.c71
-rw-r--r--camel/providers/local/camel-local-summary.c8
-rw-r--r--camel/providers/local/camel-local-summary.h6
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? */