[dovecot-cvs] dovecot/src/lib-storage/index/cydir cydir-save.c, 1.6, 1.7

tss at dovecot.org tss at dovecot.org
Wed May 16 21:32:40 EEST 2007


Update of /var/lib/cvs/dovecot/src/lib-storage/index/cydir
In directory talvi:/tmp/cvs-serv723

Modified Files:
	cydir-save.c 
Log Message:
Don't leak memory and file descriptors in appends. fsync() unless it's
disabled.



Index: cydir-save.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/cydir/cydir-save.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cydir-save.c	13 May 2007 17:10:50 -0000	1.6
+++ cydir-save.c	16 May 2007 18:32:37 -0000	1.7
@@ -11,6 +11,7 @@
 #include "cydir-sync.h"
 
 #include <stdio.h>
+#include <utime.h>
 
 struct cydir_save_context {
 	struct mail_save_context ctx;
@@ -28,6 +29,7 @@
 	struct istream *input;
 	struct ostream *output;
 	struct mail *mail;
+	int fd;
 
 	unsigned int failed:1;
 	unsigned int finished:1;
@@ -68,13 +70,9 @@
 	enum mail_flags save_flags;
 	struct ostream *output;
 	const char *path;
-	int fd;
 
 	i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
 
-	if (received_date == (time_t)-1)
-		received_date = ioloop_time;
-
 	if (ctx == NULL) {
 		ctx = t->save_ctx = i_new(struct cydir_save_context, 1);
 		ctx->ctx.transaction = &t->ictx.mailbox_ctx;
@@ -86,11 +84,23 @@
 
 	t_push();
 	path = cydir_get_save_path(ctx, ctx->mail_count);
-	fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0660);
-	if (fd != -1) {
-		output = o_stream_create_file(fd, default_pool, 0, TRUE);
+	ctx->fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0660);
+	if (ctx->fd != -1) {
+		output = o_stream_create_file(ctx->fd, default_pool, 0, FALSE);
 		ctx->output = o_stream_create_crlf(default_pool, output);
 		o_stream_unref(&output);
+
+		if (received_date != (time_t)-1) {
+			struct utimbuf ut;
+
+			ut.actime = ioloop_time;
+			ut.modtime = received_date;
+			if (utime(path, &ut) < 0) {
+				mail_storage_set_critical(_t->box->storage,
+					"utime(%s) failed: %m", path);
+				/* ignore this error anyway */
+			}
+		}
 	} else {
 		mail_storage_set_critical(_t->box->storage,
 					  "open(%s) failed: %m", path);
@@ -145,9 +155,27 @@
 int cydir_save_finish(struct mail_save_context *_ctx)
 {
 	struct cydir_save_context *ctx = (struct cydir_save_context *)_ctx;
+	struct mail_storage *storage = &ctx->mbox->storage->storage;
 
 	ctx->finished = TRUE;
 
+	if (!ctx->mbox->ibox.fsync_disable) {
+		if (fsync(ctx->fd) < 0) {
+			mail_storage_set_critical(storage,
+				"fsync(%s) failed: %m",
+				cydir_get_save_path(ctx, ctx->mail_count));
+			ctx->failed = TRUE;
+		}
+	}
+
+	o_stream_destroy(&ctx->output);
+	if (close(ctx->fd) < 0) {
+		mail_storage_set_critical(storage, "close(%s) failed: %m",
+			cydir_get_save_path(ctx, ctx->mail_count));
+		ctx->failed = TRUE;
+	}
+	ctx->fd = -1;
+
 	if (!ctx->failed)
 		ctx->mail_count++;
 



More information about the dovecot-cvs mailing list