changeset 3879:928229f8b3e6 HEAD

deinit, unref, destroy, close, free, etc. functions now take a pointer to their data pointer, and set it to NULL. This makes double-frees less likely to cause security holes.
author Timo Sirainen <tss@iki.fi>
date Sat, 14 Jan 2006 20:47:20 +0200
parents bf0a03691989
children d194896d58e6
files src/auth/auth-cache.c src/auth/auth-cache.h src/auth/auth-client-connection.c src/auth/auth-client-connection.h src/auth/auth-master-connection.c src/auth/auth-master-connection.h src/auth/auth-master-listener.c src/auth/auth-master-listener.h src/auth/auth-module.c src/auth/auth-module.h src/auth/auth-request-handler.c src/auth/auth-request-handler.h src/auth/auth-request.c src/auth/auth-request.h src/auth/auth-worker-client.c src/auth/auth-worker-client.h src/auth/auth-worker-server.c src/auth/auth.c src/auth/auth.h src/auth/db-ldap.c src/auth/db-ldap.h src/auth/db-passwd-file.c src/auth/db-passwd-file.h src/auth/db-sql.c src/auth/db-sql.h src/auth/main.c src/auth/mech-gssapi.c src/auth/passdb-cache.c src/auth/passdb-checkpassword.c src/auth/passdb-ldap.c src/auth/passdb-pam.c src/auth/passdb-passwd-file.c src/auth/passdb-sql.c src/auth/passdb.c src/auth/password-scheme.c src/auth/userdb-ldap.c src/auth/userdb-passwd-file.c src/auth/userdb-sql.c src/auth/userdb.c src/dict/dict-cache.c src/dict/dict-server.c src/dict/main.c src/imap-login/client-authenticate.c src/imap-login/client.c src/imap-login/imap-proxy.c src/imap/client.c src/imap/cmd-append.c src/imap/cmd-close.c src/imap/cmd-copy.c src/imap/cmd-delete.c src/imap/cmd-idle.c src/imap/cmd-list.c src/imap/cmd-logout.c src/imap/cmd-search.c src/imap/cmd-select.c src/imap/cmd-status.c src/imap/cmd-store.c src/imap/cmd-unselect.c src/imap/imap-expunge.c src/imap/imap-fetch-body.c src/imap/imap-fetch.c src/imap/imap-sort.c src/imap/imap-sync.c src/imap/imap-thread.c src/imap/main.c src/imap/namespace.c src/lib-auth/auth-client.c src/lib-auth/auth-client.h src/lib-auth/auth-server-connection.c src/lib-auth/auth-server-connection.h src/lib-auth/auth-server-request.c src/lib-charset/charset-iconv.c src/lib-charset/charset-utf8.c src/lib-charset/charset-utf8.h src/lib-dict/dict-client.c src/lib-dict/dict-sql.c src/lib-dict/dict.c src/lib-dict/dict.h src/lib-imap/imap-base-subject.c src/lib-imap/imap-bodystructure.c src/lib-imap/imap-envelope.c src/lib-imap/imap-match.c src/lib-imap/imap-match.h src/lib-imap/imap-parser.c src/lib-imap/imap-parser.h src/lib-index/mail-cache-compress.c src/lib-index/mail-cache.c src/lib-index/mail-cache.h src/lib-index/mail-index-private.h src/lib-index/mail-index-sync-update.c src/lib-index/mail-index-sync.c src/lib-index/mail-index-transaction-private.h src/lib-index/mail-index-transaction-view.c src/lib-index/mail-index-transaction.c src/lib-index/mail-index-view-sync.c src/lib-index/mail-index-view.c src/lib-index/mail-index.c src/lib-index/mail-index.h src/lib-index/mail-transaction-log-view.c src/lib-index/mail-transaction-log.c src/lib-index/mail-transaction-log.h src/lib-mail/istream-header-filter.c src/lib-mail/message-body-search.c src/lib-mail/message-header-search.c src/lib-mail/message-header-search.h src/lib-mail/message-parser.c src/lib-mail/message-parser.h src/lib-settings/settings.c src/lib-sql/driver-mysql.c src/lib-sql/driver-pgsql.c src/lib-sql/sql-api.c src/lib-sql/sql-api.h src/lib-storage/index/dbox/dbox-file.c src/lib-storage/index/dbox/dbox-list.c src/lib-storage/index/dbox/dbox-save.c src/lib-storage/index/dbox/dbox-sync-expunge.c src/lib-storage/index/dbox/dbox-sync.c src/lib-storage/index/dbox/dbox-uidlist.c src/lib-storage/index/index-mail-headers.c src/lib-storage/index/index-mail.c src/lib-storage/index/index-mailbox-check.c src/lib-storage/index/index-search.c src/lib-storage/index/index-storage.c src/lib-storage/index/index-sync.c src/lib-storage/index/index-transaction.c src/lib-storage/index/maildir/maildir-keywords.c src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/index/maildir/maildir-uidlist.c src/lib-storage/index/mbox/istream-raw-mbox.c src/lib-storage/index/mbox/mbox-file.c src/lib-storage/index/mbox/mbox-list.c src/lib-storage/index/mbox/mbox-mail.c src/lib-storage/index/mbox/mbox-save.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/index/mbox/mbox-sync-parse.c src/lib-storage/index/mbox/mbox-sync-rewrite.c src/lib-storage/index/mbox/mbox-sync.c src/lib-storage/mail-copy.c src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/lib-storage/mail.c src/lib-storage/subscription-file/subscription-file.c src/lib/buffer.c src/lib/buffer.h src/lib/file-cache.c src/lib/file-cache.h src/lib/hash.c src/lib/hash.h src/lib/ioloop-notify-dn.c src/lib/ioloop.c src/lib/ioloop.h src/lib/istream-limit.c src/lib/istream-seekable.c src/lib/istream.c src/lib/istream.h src/lib/lib-signals.c src/lib/module-dir.c src/lib/module-dir.h src/lib/ostream-crlf.c src/lib/ostream-file.c src/lib/ostream.c src/lib/ostream.h src/lib/str.c src/lib/str.h src/login-common/login-proxy.c src/login-common/main.c src/login-common/master.c src/login-common/ssl-proxy-openssl.c src/master/auth-process.c src/master/dict-process.c src/master/log.c src/master/login-process.c src/master/main.c src/master/ssl-init.c src/plugins/imap-quota/imap-quota-plugin.c src/plugins/quota/quota-storage.c src/plugins/trash/trash-plugin.c src/plugins/zlib/zlib-plugin.c src/pop3-login/client-authenticate.c src/pop3-login/client.c src/pop3-login/pop3-proxy.c src/pop3/client.c src/pop3/commands.c src/pop3/main.c src/util/rawlog.c
diffstat 186 files changed, 907 insertions(+), 861 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/auth-cache.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-cache.c	Sat Jan 14 20:47:20 2006 +0200
@@ -52,7 +52,7 @@
 			}
 		}
 	}
-	return str_free_without_data(str);
+	return str_free_without_data(&str);
 }
 
 static void
@@ -133,8 +133,11 @@
 	return cache;
 }
 
-void auth_cache_free(struct auth_cache *cache)
+void auth_cache_free(struct auth_cache **_cache)
 {
+	struct auth_cache *cache = *_cache;
+
+	*_cache = NULL;
 	lib_signals_unset_handler(SIGHUP, sig_auth_cache_clear, cache);
 	lib_signals_unset_handler(SIGUSR2, sig_auth_cache_stats, cache);
 
--- a/src/auth/auth-cache.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-cache.h	Sat Jan 14 20:47:20 2006 +0200
@@ -12,7 +12,7 @@
    bytes to use for cache (it's not fully exact). ttl_secs specifies time to
    live for cache record, requests older than that are not used. */
 struct auth_cache *auth_cache_new(size_t max_size, unsigned int ttl_secs);
-void auth_cache_free(struct auth_cache *cache);
+void auth_cache_free(struct auth_cache **cache);
 
 /* Clear the cache. */
 void auth_cache_clear(struct auth_cache *cache);
--- a/src/auth/auth-client-connection.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-client-connection.c	Sat Jan 14 20:47:20 2006 +0200
@@ -18,7 +18,7 @@
 
 #define OUTBUF_THROTTLE_SIZE (1024*50)
 
-static void auth_client_connection_unref(struct auth_client_connection *conn);
+static void auth_client_connection_unref(struct auth_client_connection **_conn);
 
 static void auth_client_input(void *context);
 static void auth_client_send(struct auth_client_connection *conn,
@@ -47,10 +47,8 @@
 	    OUTBUF_THROTTLE_SIZE) {
 		/* stop reading new requests until client has read the pending
 		   replies. */
-		if (conn->io != NULL) {
-			io_remove(conn->io);
-			conn->io = NULL;
-		}
+		if (conn->io != NULL)
+			io_remove(&conn->io);
 	}
 	va_end(args);
 	t_pop();
@@ -62,7 +60,7 @@
 
 	if (reply == NULL) {
 		/* handler destroyed */
-		auth_client_connection_unref(conn);
+		auth_client_connection_unref(&conn);
 		return;
 	}
 
@@ -89,7 +87,7 @@
 		   see if the old connection is still there. */
 		i_assert(old != conn);
 		if (i_stream_read(old->input) == -1) {
-                        auth_client_connection_destroy(old);
+                        auth_client_connection_destroy(&old);
 			old = NULL;
 		}
 	}
@@ -118,7 +116,7 @@
 	struct auth_client_connection *conn = context;
 
 	if (o_stream_flush(conn->output) < 0) {
-		auth_client_connection_destroy(conn);
+		auth_client_connection_destroy(&conn);
 		return 1;
 	}
 
@@ -160,13 +158,13 @@
 		return;
 	case -1:
 		/* disconnected */
-		auth_client_connection_destroy(conn);
+		auth_client_connection_destroy(&conn);
 		return;
 	case -2:
 		/* buffer full */
 		i_error("BUG: Auth client %u sent us more than %d bytes",
 			conn->pid, (int)AUTH_CLIENT_MAX_LINE_LENGTH);
-		auth_client_connection_destroy(conn);
+		auth_client_connection_destroy(&conn);
 		return;
 	}
 
@@ -184,7 +182,7 @@
 				i_error("Authentication client "
 					"not compatible with this server "
 					"(mixed old and new binaries?)");
-				auth_client_connection_destroy(conn);
+				auth_client_connection_destroy(&conn);
 				return;
 			}
 			conn->version_received = TRUE;
@@ -193,7 +191,7 @@
 
 		if (strncmp(line, "CPID\t", 5) == 0) {
 			if (!auth_client_input_cpid(conn, line + 5)) {
-				auth_client_connection_destroy(conn);
+				auth_client_connection_destroy(&conn);
 				return;
 			}
 		}
@@ -207,11 +205,11 @@
 		t_pop();
 
 		if (!ret) {
-			auth_client_connection_destroy(conn);
+			auth_client_connection_destroy(&conn);
 			break;
 		}
 	}
-	auth_client_connection_unref(conn);
+	auth_client_connection_unref(&conn);
 }
 
 struct auth_client_connection *
@@ -250,19 +248,19 @@
 	iov[1].iov_base = str_data(str);
 	iov[1].iov_len = str_len(str);
 
-	if (o_stream_sendv(conn->output, iov, 2) < 0) {
-		auth_client_connection_destroy(conn);
-		conn = NULL;
-	}
+	if (o_stream_sendv(conn->output, iov, 2) < 0)
+		auth_client_connection_destroy(&conn);
 
 	return conn;
 }
 
-void auth_client_connection_destroy(struct auth_client_connection *conn)
+void auth_client_connection_destroy(struct auth_client_connection **_conn)
 {
+        struct auth_client_connection *conn = *_conn;
 	struct auth_client_connection *const *clients;
 	unsigned int i, count;
 
+	*_conn = NULL;
 	if (conn->fd == -1)
 		return;
 
@@ -277,27 +275,28 @@
 	i_stream_close(conn->input);
 	o_stream_close(conn->output);
 
-	if (conn->io != NULL) {
-		io_remove(conn->io);
-		conn->io = NULL;
-	}
+	if (conn->io != NULL)
+		io_remove(&conn->io);
 
 	net_disconnect(conn->fd);
 	conn->fd = -1;
 
 	if (conn->request_handler != NULL)
-		auth_request_handler_unref(conn->request_handler);
+		auth_request_handler_unref(&conn->request_handler);
 
-        auth_client_connection_unref(conn);
+        auth_client_connection_unref(&conn);
 }
 
-static void auth_client_connection_unref(struct auth_client_connection *conn)
+static void auth_client_connection_unref(struct auth_client_connection **_conn)
 {
+        struct auth_client_connection *conn = *_conn;
+
+	*_conn = NULL;
 	if (--conn->refcount > 0)
 		return;
 
-	i_stream_unref(conn->input);
-	o_stream_unref(conn->output);
+	i_stream_unref(&conn->input);
+	o_stream_unref(&conn->output);
 	i_free(conn);
 }
 
@@ -339,8 +338,6 @@
 
 void auth_client_connections_deinit(struct auth_master_listener *listener)
 {
-	if (listener->to_clients != NULL) {
-		timeout_remove(listener->to_clients);
-		listener->to_clients = NULL;
-	}
+	if (listener->to_clients != NULL)
+		timeout_remove(&listener->to_clients);
 }
--- a/src/auth/auth-client-connection.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-client-connection.h	Sat Jan 14 20:47:20 2006 +0200
@@ -20,7 +20,7 @@
 
 struct auth_client_connection *
 auth_client_connection_create(struct auth_master_listener *listener, int fd);
-void auth_client_connection_destroy(struct auth_client_connection *conn);
+void auth_client_connection_destroy(struct auth_client_connection **conn);
 
 struct auth_client_connection *
 auth_client_connection_lookup(struct auth_master_listener *listener,
--- a/src/auth/auth-master-connection.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-master-connection.c	Sat Jan 14 20:47:20 2006 +0200
@@ -97,7 +97,7 @@
 		i_info("master out: %s", str_c(str));
 
 	(void)o_stream_send(conn->output, str_data(str), str_len(str));
-	auth_request_unref(auth_request);
+	auth_request_unref(&auth_request);
 }
 
 static bool
@@ -133,7 +133,7 @@
 
 	if (auth_request->service == NULL) {
 		i_error("BUG: Master sent USER request without service");
-		auth_request_unref(auth_request);
+		auth_request_unref(&auth_request);
 		return FALSE;
 	}
 
@@ -158,13 +158,13 @@
 		return;
 	case -1:
 		/* disconnected */
-                auth_master_connection_destroy(conn);
+                auth_master_connection_destroy(&conn);
 		return;
 	case -2:
 		/* buffer full */
 		i_error("BUG: Master sent us more than %d bytes",
 			(int)MAX_INBUF_SIZE);
-                auth_master_connection_destroy(conn);
+                auth_master_connection_destroy(&conn);
 		return;
 	}
 
@@ -179,7 +179,7 @@
 		    AUTH_MASTER_PROTOCOL_MAJOR_VERSION) {
 			i_error("Master not compatible with this server "
 				"(mixed old and new binaries?)");
-			auth_master_connection_destroy(conn);
+			auth_master_connection_destroy(&conn);
 			return;
 		}
 		conn->version_received = TRUE;
@@ -203,7 +203,7 @@
 		t_pop();
 
 		if (!ret) {
-			auth_master_connection_destroy(conn);
+			auth_master_connection_destroy(&conn);
 			return;
 		}
 	}
@@ -216,7 +216,7 @@
 
 	if ((ret = o_stream_flush(conn->output)) < 0) {
 		/* transmit error, probably master died */
-		auth_master_connection_destroy(conn);
+		auth_master_connection_destroy(&conn);
 		return 1;
 	}
 
@@ -260,11 +260,13 @@
 	(void)o_stream_send_str(conn->output, line);
 }
 
-void auth_master_connection_destroy(struct auth_master_connection *conn)
+void auth_master_connection_destroy(struct auth_master_connection **_conn)
 {
+        struct auth_master_connection *conn = *_conn;
         struct auth_master_connection *const *conns;
 	unsigned int i, count;
 
+	*_conn = NULL;
 	if (conn->destroyed)
 		return;
 	conn->destroyed = TRUE;
@@ -274,11 +276,11 @@
 			i_error("close(): %m");
 	}
 	if (conn->input != NULL)
-		i_stream_unref(conn->input);
+		i_stream_unref(&conn->input);
 	if (conn->output != NULL)
-		o_stream_unref(conn->output);
+		o_stream_unref(&conn->output);
 	if (conn->io != NULL)
-		io_remove(conn->io);
+		io_remove(&conn->io);
 
 	conns = array_get(&conn->listener->masters, &count);
 	for (i = 0; i < count; i++) {
--- a/src/auth/auth-master-connection.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-master-connection.h	Sat Jan 14 20:47:20 2006 +0200
@@ -15,7 +15,7 @@
 
 struct auth_master_connection *
 auth_master_connection_create(struct auth_master_listener *listener, int fd);
-void auth_master_connection_destroy(struct auth_master_connection *conn);
+void auth_master_connection_destroy(struct auth_master_connection **conn);
 
 void auth_master_connection_send_handshake(struct auth_master_connection *conn);
 void auth_master_connections_send_handshake(void);
--- a/src/auth/auth-master-listener.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-master-listener.c	Sat Jan 14 20:47:20 2006 +0200
@@ -51,18 +51,21 @@
 	}
 
 	net_disconnect(socket->fd);
-	io_remove(socket->io);
+	io_remove(&socket->io);
 	i_free(socket);
 }
 
-void auth_master_listener_destroy(struct auth_master_listener *listener)
+void auth_master_listener_destroy(struct auth_master_listener **_listener)
 {
+        struct auth_master_listener *listener = *_listener;
 	struct auth_master_listener *const *listeners;
-	struct auth_master_listener_socket *const *sockets;
-	struct auth_master_connection *const *masters;
-	struct auth_client_connection *const *clients;
+	struct auth_master_listener_socket **sockets;
+	struct auth_master_connection **masters;
+	struct auth_client_connection **clients;
 	unsigned int i, count;
 
+	*_listener = NULL;
+
 	listeners = array_get(&master_listeners, &count);
 	for (i = 0; i < count; i++) {
 		if (listeners[i] == listener) {
@@ -71,17 +74,17 @@
 		}
 	}
 
-	sockets = array_get(&listener->sockets, &count);
+	sockets = array_get_modifyable(&listener->sockets, &count);
 	for (i = count; i > 0; i--)
 		auth_master_listener_socket_free(sockets[i-1]);
 
-	masters = array_get(&listener->masters, &count);
+	masters = array_get_modifyable(&listener->masters, &count);
 	for (i = count; i > 0; i--)
-		auth_master_connection_destroy(masters[i-1]);
+		auth_master_connection_destroy(&masters[i-1]);
 
-	clients = array_get(&listener->clients, &count);
+	clients = array_get_modifyable(&listener->clients, &count);
 	for (i = count; i > 0; i--)
-		auth_client_connection_destroy(clients[i-1]);
+		auth_client_connection_destroy(&clients[i-1]);
 
         auth_client_connections_deinit(listener);
 	array_free(&listener->sockets);
@@ -174,11 +177,11 @@
 
 void auth_master_listeners_deinit(void)
 {
-        struct auth_master_listener *const *listeners;
+        struct auth_master_listener **listeners;
 	unsigned int i, count;
 
-	listeners = array_get(&master_listeners, &count);
+	listeners = array_get_modifyable(&master_listeners, &count);
 	for (i = count; i > 0; i--)
-		auth_master_listener_destroy(listeners[i-1]);
+		auth_master_listener_destroy(&listeners[i-1]);
 	array_free(&master_listeners);
 }
--- a/src/auth/auth-master-listener.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-master-listener.h	Sat Jan 14 20:47:20 2006 +0200
@@ -18,7 +18,7 @@
 };
 
 struct auth_master_listener *auth_master_listener_create(struct auth *auth);
-void auth_master_listener_destroy(struct auth_master_listener *listener);
+void auth_master_listener_destroy(struct auth_master_listener **listener);
 
 void auth_master_listener_add(struct auth_master_listener *listener,
 			      int fd, const char *path,
--- a/src/auth/auth-module.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-module.c	Sat Jan 14 20:47:20 2006 +0200
@@ -73,10 +73,12 @@
 	return module;
 }
 
-void auth_module_close(struct auth_module *module)
+void auth_module_close(struct auth_module **_module)
 {
+        struct auth_module *module = *_module;
 	struct auth_module **pos;
 
+	*_module = NULL;
 	if (--module->refcount > 0)
 		return;
 
--- a/src/auth/auth-module.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-module.h	Sat Jan 14 20:47:20 2006 +0200
@@ -2,7 +2,7 @@
 #define __AUTH_MODULE_H
 
 struct auth_module *auth_module_open(const char *name);
-void auth_module_close(struct auth_module *module);
+void auth_module_close(struct auth_module **module);
 
 void *auth_module_sym(struct auth_module *module, const char *name);
 
--- a/src/auth/auth-request-handler.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-request-handler.c	Sat Jan 14 20:47:20 2006 +0200
@@ -50,11 +50,13 @@
 	return handler;
 }
 
-void auth_request_handler_unref(struct auth_request_handler *handler)
+void auth_request_handler_unref(struct auth_request_handler **_handler)
 {
+        struct auth_request_handler *handler = *_handler;
 	struct hash_iterate_context *iter;
 	void *key, *value;
 
+	*_handler = NULL;
 	i_assert(handler->refcount > 0);
 	if (--handler->refcount > 0)
 		return;
@@ -83,7 +85,7 @@
 					struct auth_request *request)
 {
 	hash_remove(handler->requests, POINTER_CAST(request->id));
-	auth_request_unref(request);
+	auth_request_unref(&request);
 }
 
 void auth_request_handler_check_timeouts(struct auth_request_handler *handler)
@@ -200,7 +202,7 @@
 			/* passdb specifically requested not to delay the
 			   reply. */
 			handler->callback(str_c(str), handler->context);
-			auth_request_unref(request);
+			auth_request_unref(&request);
 		} else {
 			/* failure. don't announce it immediately to avoid
 			   a) timing attacks, b) flooding */
@@ -213,7 +215,7 @@
 	}
 	/* NOTE: request may be destroyed now */
 
-        auth_request_handler_unref(handler);
+        auth_request_handler_unref(&handler);
 
 	t_pop();
 }
@@ -293,7 +295,7 @@
 		i_error("BUG: Authentication client %u "
 			"didn't specify service in request",
 			handler->client_pid);
-		auth_request_unref(request);
+		auth_request_unref(&request);
 		return FALSE;
 	}
 
@@ -396,8 +398,8 @@
 	}
 	handler->master_callback(str_c(str), request->master);
 
-	auth_request_unref(request);
-        auth_request_handler_unref(handler);
+	auth_request_unref(&request);
+        auth_request_handler_unref(&handler);
 }
 
 void auth_request_handler_master_request(struct auth_request_handler *handler,
@@ -455,7 +457,7 @@
 		i_assert(auth_request[i]->state == AUTH_REQUEST_STATE_FINISHED);
 		auth_request[i]->callback(auth_request[i],
 					  AUTH_CLIENT_RESULT_FAILURE, NULL, 0);
-		auth_request_unref(auth_request[i]);
+		auth_request_unref(&auth_request[i]);
 	}
 	buffer_set_used_size(auth_failures_buf, 0);
 }
@@ -474,5 +476,5 @@
 void auth_request_handler_deinit(void)
 {
 	buffer_free(auth_failures_buf);
-	timeout_remove(to_auth_failures);
+	timeout_remove(&to_auth_failures);
 }
--- a/src/auth/auth-request-handler.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-request-handler.h	Sat Jan 14 20:47:20 2006 +0200
@@ -10,7 +10,7 @@
 auth_request_handler_create(struct auth *auth,
 			    auth_request_callback_t *callback, void *context,
 			    auth_request_callback_t *master_callback);
-void auth_request_handler_unref(struct auth_request_handler *handler);
+void auth_request_handler_unref(struct auth_request_handler **handler);
 
 void auth_request_handler_set(struct auth_request_handler *handler,
 			      unsigned int connect_uid,
--- a/src/auth/auth-request.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-request.c	Sat Jan 14 20:47:20 2006 +0200
@@ -87,17 +87,19 @@
 	request->refcount++;
 }
 
-bool auth_request_unref(struct auth_request *request)
+void auth_request_unref(struct auth_request **_request)
 {
+	struct auth_request *request = *_request;
+
+	*_request = NULL;
 	i_assert(request->refcount > 0);
 	if (--request->refcount > 0)
-		return TRUE;
+		return;
 
 	if (request->mech != NULL)
 		request->mech->auth_free(request);
 	else
 		pool_unref(request->pool);
-	return FALSE;
 }
 
 void auth_request_export(struct auth_request *request, string_t *str)
@@ -317,7 +319,7 @@
 		request->private_callback.verify_plain(result, request);
 		safe_memset(request->mech_password, 0,
 			    strlen(request->mech_password));
-		auth_request_unref(request);
+		auth_request_unref(&request);
 	}
 }
 
--- a/src/auth/auth-request.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-request.h	Sat Jan 14 20:47:20 2006 +0200
@@ -69,7 +69,7 @@
 		 mech_callback_t *callback, void *context);
 struct auth_request *auth_request_new_dummy(struct auth *auth);
 void auth_request_ref(struct auth_request *request);
-bool auth_request_unref(struct auth_request *request);
+void auth_request_unref(struct auth_request **request);
 
 void auth_request_success(struct auth_request *request,
 			  const void *data, size_t data_size);
--- a/src/auth/auth-worker-client.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-worker-client.c	Sat Jan 14 20:47:20 2006 +0200
@@ -36,10 +36,8 @@
 	    OUTBUF_THROTTLE_SIZE) {
 		/* stop reading new requests until client has read the pending
 		   replies. */
-		if (client->io != NULL) {
-			io_remove(client->io);
-			client->io = NULL;
-		}
+		if (client->io != NULL)
+			io_remove(&client->io);
 	}
 }
 
@@ -101,9 +99,9 @@
 	str_append_c(str, '\n');
 	o_stream_send(client->output, str_data(str), str_len(str));
 
-	auth_request_unref(request);
+	auth_request_unref(&request);
 	auth_worker_client_check_throttle(client);
-	auth_worker_client_unref(client);
+	auth_worker_client_unref(&client);
 }
 
 static void
@@ -133,7 +131,7 @@
 
 	if (auth_request->user == NULL || auth_request->service == NULL) {
 		i_error("BUG: PASSV had missing parameters");
-		auth_request_unref(auth_request);
+		auth_request_unref(&auth_request);
 		return;
 	}
 
@@ -141,7 +139,7 @@
 		auth_request->passdb = auth_request->passdb->next;
 		if (auth_request->passdb == NULL) {
 			i_error("BUG: PASSV had invalid passdb num");
-			auth_request_unref(auth_request);
+			auth_request_unref(&auth_request);
 			return;
 		}
 	}
@@ -175,9 +173,9 @@
 	str_append_c(str, '\n');
 	o_stream_send(client->output, str_data(str), str_len(str));
 
-	auth_request_unref(request);
+	auth_request_unref(&request);
 	auth_worker_client_check_throttle(client);
-	auth_worker_client_unref(client);
+	auth_worker_client_unref(&client);
 }
 
 static void
@@ -209,7 +207,7 @@
 
 	if (auth_request->user == NULL || auth_request->service == NULL) {
 		i_error("BUG: PASSL had missing parameters");
-		auth_request_unref(auth_request);
+		auth_request_unref(&auth_request);
 		return;
 	}
 
@@ -217,7 +215,7 @@
 		auth_request->passdb = auth_request->passdb->next;
 		if (auth_request->passdb == NULL) {
 			i_error("BUG: PASSL had invalid passdb num");
-			auth_request_unref(auth_request);
+			auth_request_unref(&auth_request);
 			return;
 		}
 	}
@@ -241,9 +239,9 @@
 
 	o_stream_send(client->output, str_data(str), str_len(str));
 
-	auth_request_unref(auth_request);
+	auth_request_unref(&auth_request);
 	auth_worker_client_check_throttle(client);
-	auth_worker_client_unref(client);
+	auth_worker_client_unref(&client);
 }
 
 static void
@@ -262,7 +260,7 @@
 
 	if (auth_request->user == NULL || auth_request->service == NULL) {
 		i_error("BUG: USER had missing parameters");
-		auth_request_unref(auth_request);
+		auth_request_unref(&auth_request);
 		return;
 	}
 
@@ -270,7 +268,7 @@
 		auth_request->userdb = auth_request->userdb->next;
 		if (auth_request->userdb == NULL) {
 			i_error("BUG: USER had invalid userdb num");
-			auth_request_unref(auth_request);
+			auth_request_unref(&auth_request);
 			return;
 		}
 	}
@@ -313,13 +311,13 @@
 		return;
 	case -1:
 		/* disconnected */
-		auth_worker_client_destroy(client);
+		auth_worker_client_destroy(&client);
 		return;
 	case -2:
 		/* buffer full */
 		i_error("BUG: Auth worker server sent us more than %d bytes",
 			(int)AUTH_WORKER_MAX_LINE_LENGTH);
-		auth_worker_client_destroy(client);
+		auth_worker_client_destroy(&client);
 		return;
 	}
 
@@ -332,11 +330,11 @@
 		t_pop();
 
 		if (!ret) {
-			auth_worker_client_destroy(client);
+			auth_worker_client_destroy(&client);
 			break;
 		}
 	}
-	auth_worker_client_unref(client);
+	auth_worker_client_unref(&client);
 }
 
 static int auth_worker_output(void *context)
@@ -344,7 +342,7 @@
 	struct auth_worker_client *client = context;
 
 	if (o_stream_flush(client->output) < 0) {
-		auth_worker_client_destroy(client);
+		auth_worker_client_destroy(&client);
 		return 1;
 	}
 
@@ -362,7 +360,7 @@
 	struct auth_worker_client *client = context;
 
 	if (client->last_request + AUTH_WORKER_MAX_IDLE <= ioloop_time)
-                auth_worker_client_destroy(client);
+                auth_worker_client_destroy(&client);
 }
 
 struct auth_worker_client *
@@ -389,20 +387,21 @@
 	return client;
 }
 
-void auth_worker_client_destroy(struct auth_worker_client *client)
+void auth_worker_client_destroy(struct auth_worker_client **_client)
 {
+	struct auth_worker_client *client = *_client;
+
+	*_client = NULL;
 	if (client->fd == -1)
 		return;
 
-	timeout_remove(client->to);
+	timeout_remove(&client->to);
 
 	i_stream_close(client->input);
 	o_stream_close(client->output);
 
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
+	if (client->io != NULL)
+		io_remove(&client->io);
 
 	net_disconnect(client->fd);
 	client->fd = -1;
@@ -410,15 +409,19 @@
 	io_loop_stop(ioloop);
 }
 
-void auth_worker_client_unref(struct auth_worker_client *client)
+void auth_worker_client_unref(struct auth_worker_client **_client)
 {
-	if (--client->refcount > 0)
+	struct auth_worker_client *client = *_client;
+
+	if (--client->refcount > 0) {
+		*_client = NULL;
 		return;
+	}
 
 	if (client->fd != -1)
-		auth_worker_client_destroy(client);
+		auth_worker_client_destroy(_client);
 
-	i_stream_unref(client->input);
-	o_stream_unref(client->output);
+	i_stream_unref(&client->input);
+	o_stream_unref(&client->output);
 	i_free(client);
 }
--- a/src/auth/auth-worker-client.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-worker-client.h	Sat Jan 14 20:47:20 2006 +0200
@@ -4,7 +4,7 @@
 #define AUTH_WORKER_MAX_LINE_LENGTH 1024
 
 struct auth_worker_client *auth_worker_client_create(struct auth *auth, int fd);
-void auth_worker_client_destroy(struct auth_worker_client *client);
-void auth_worker_client_unref(struct auth_worker_client *client);
+void auth_worker_client_destroy(struct auth_worker_client **client);
+void auth_worker_client_unref(struct auth_worker_client **client);
 
 #endif
--- a/src/auth/auth-worker-server.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth-worker-server.c	Sat Jan 14 20:47:20 2006 +0200
@@ -121,7 +121,7 @@
 	for (i = 0; i < size; i++) {
 		if (request[i].id != 0) {
 			request[i].callback(request[i].auth_request, reply);
-			auth_request_unref(request[i].auth_request);
+			auth_request_unref(&request[i].auth_request);
 		}
 	}
 
@@ -129,9 +129,9 @@
 		i_error("close(auth worker) failed: %m");
 
 	buffer_free(conn->requests);
-	io_remove(conn->io);
-	i_stream_unref(conn->input);
-	o_stream_unref(conn->output);
+	io_remove(&conn->io);
+	i_stream_unref(&conn->input);
+	o_stream_unref(&conn->output);
 	i_free(conn);
 }
 
@@ -189,7 +189,7 @@
 				       const char *line)
 {
 	request->callback(request->auth_request, line);
-	auth_request_unref(request->auth_request);
+	auth_request_unref(&request->auth_request);
 
 	/* mark the record empty so it can be used for future requests */
 	memset(request, 0, sizeof(*request));
@@ -378,6 +378,6 @@
 	buffer_free(connections);
 	connections = NULL;
 
-	timeout_remove(to);
+	timeout_remove(&to);
 	i_free(worker_socket_path);
 }
--- a/src/auth/auth.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth.c	Sat Jan 14 20:47:20 2006 +0200
@@ -228,11 +228,14 @@
 		getenv("SSL_USERNAME_FROM_CERT") != NULL;
 }
 
-void auth_deinit(struct auth *auth)
+void auth_deinit(struct auth **_auth)
 {
+        struct auth *auth = *_auth;
 	struct auth_passdb *passdb;
 	struct auth_userdb *userdb;
 
+	*_auth = NULL;
+
 	passdb_cache_deinit();
 	for (passdb = auth->passdbs; passdb != NULL; passdb = passdb->next)
 		passdb_deinit(passdb);
--- a/src/auth/auth.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/auth.h	Sat Jan 14 20:47:20 2006 +0200
@@ -51,6 +51,6 @@
 
 struct auth *auth_preinit(void);
 void auth_init(struct auth *auth);
-void auth_deinit(struct auth *auth);
+void auth_deinit(struct auth **auth);
 
 #endif
--- a/src/auth/db-ldap.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/db-ldap.c	Sat Jan 14 20:47:20 2006 +0200
@@ -298,10 +298,8 @@
 
 	conn->connected = FALSE;
 
-	if (conn->io != NULL) {
-		io_remove(conn->io);
-		conn->io = NULL;
-	}
+	if (conn->io != NULL)
+		io_remove(&conn->io);
 
 	if (conn->ld != NULL) {
 		ldap_unbind(conn->ld);
@@ -453,10 +451,12 @@
 	return conn;
 }
 
-void db_ldap_unref(struct ldap_connection *conn)
+void db_ldap_unref(struct ldap_connection **_conn)
 {
+        struct ldap_connection *conn = *_conn;
 	struct ldap_connection **p;
 
+	*_conn = NULL;
 	i_assert(conn->refcount >= 0);
 	if (--conn->refcount > 0)
 		return;
--- a/src/auth/db-ldap.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/db-ldap.h	Sat Jan 14 20:47:20 2006 +0200
@@ -73,7 +73,7 @@
 		       const char *const default_attr_map[]);
 
 struct ldap_connection *db_ldap_init(const char *config_path);
-void db_ldap_unref(struct ldap_connection *conn);
+void db_ldap_unref(struct ldap_connection **conn);
 
 bool db_ldap_connect(struct ldap_connection *conn);
 
--- a/src/auth/db-passwd-file.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/db-passwd-file.c	Sat Jan 14 20:47:20 2006 +0200
@@ -182,7 +182,7 @@
 		}
 		t_pop();
 	}
-	i_stream_unref(input);
+	i_stream_unref(&input);
 	return TRUE;
 }
 
@@ -312,12 +312,14 @@
 	return db;
 }
 
-void db_passwd_file_unref(struct db_passwd_file *db)
+void db_passwd_file_unref(struct db_passwd_file **_db)
 {
+        struct db_passwd_file *db = *_db;
         struct db_passwd_file **p;
 	struct hash_iterate_context *iter;
 	void *key, *value;
 
+	*_db = NULL;
 	i_assert(db->refcount >= 0);
 	if (--db->refcount > 0)
 		return;
--- a/src/auth/db-passwd-file.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/db-passwd-file.h	Sat Jan 14 20:47:20 2006 +0200
@@ -43,6 +43,6 @@
 db_passwd_file_lookup(struct db_passwd_file *db, struct auth_request *request);
 
 struct db_passwd_file *db_passwd_file_parse(const char *path, bool userdb);
-void db_passwd_file_unref(struct db_passwd_file *db);
+void db_passwd_file_unref(struct db_passwd_file **db);
 
 #endif
--- a/src/auth/db-sql.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/db-sql.c	Sat Jan 14 20:47:20 2006 +0200
@@ -88,12 +88,15 @@
 	return conn;
 }
 
-void db_sql_unref(struct sql_connection *conn)
+void db_sql_unref(struct sql_connection **_conn)
 {
+        struct sql_connection *conn = *_conn;
+
+	*_conn = NULL;
 	if (--conn->refcount > 0)
 		return;
 
-	sql_deinit(conn->db);
+	sql_deinit(&conn->db);
 	pool_unref(conn->pool);
 }
 
--- a/src/auth/db-sql.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/db-sql.h	Sat Jan 14 20:47:20 2006 +0200
@@ -23,6 +23,6 @@
 };
 
 struct sql_connection *db_sql_init(const char *config_path);
-void db_sql_unref(struct sql_connection *conn);
+void db_sql_unref(struct sql_connection **conn);
 
 #endif
--- a/src/auth/main.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/main.c	Sat Jan 14 20:47:20 2006 +0200
@@ -263,10 +263,10 @@
 
 static void main_deinit(void)
 {
-	auth_deinit(auth);
+	auth_deinit(&auth);
 
 	if (worker_client != NULL)
-		auth_worker_client_unref(worker_client);
+		auth_worker_client_unref(&worker_client);
 	else
 		auth_request_handler_flush_failures();
 
@@ -309,7 +309,7 @@
         io_loop_run(ioloop);
 	main_deinit();
 
-	io_loop_destroy(ioloop);
+	io_loop_destroy(&ioloop);
 	lib_deinit();
 
         return 0;
--- a/src/auth/mech-gssapi.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/mech-gssapi.c	Sat Jan 14 20:47:20 2006 +0200
@@ -115,7 +115,7 @@
 				       GSS_C_NT_HOSTBASED_SERVICE,
 				       &gss_principal);
 
-	str_free(principal_name);
+	str_free(&principal_name);
 
 	if (GSS_ERROR(major_status)) {
 		auth_request_log_gss_error(request, major_status,
--- a/src/auth/passdb-cache.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/passdb-cache.c	Sat Jan 14 20:47:20 2006 +0200
@@ -144,5 +144,5 @@
 void passdb_cache_deinit(void)
 {
 	if (passdb_cache != NULL)
-		auth_cache_free(passdb_cache);
+		auth_cache_free(&passdb_cache);
 }
--- a/src/auth/passdb-checkpassword.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/passdb-checkpassword.c	Sat Jan 14 20:47:20 2006 +0200
@@ -46,13 +46,11 @@
 			i_error("checkpassword: close() failed: %m");
 		request->fd_in = -1;
 	}
-	if (request->io_in != NULL) {
-		io_remove(request->io_in);
-		request->io_in = NULL;
-	}
+	if (request->io_in != NULL)
+		io_remove(&request->io_in);
 
 	if (request->io_out != NULL)
-		io_remove(request->io_out);
+		io_remove(&request->io_out);
 	if (request->fd_out != -1) {
 		if (close(request->fd_out) < 0)
 			i_error("checkpassword: close() failed: %m");
@@ -75,16 +73,13 @@
 					 str_c(request->input_buf));
 	}
 
-	if (auth_request_unref(request->request)) {
-		request->callback(result, request->request);
-	}
+	request->callback(result, request->request);
+	auth_request_unref(&request->request);
 
         checkpassword_request_close(request);
 
-	if (request->input_buf != NULL) {
-		str_free(request->input_buf);
-		request->input_buf = NULL;
-	}
+	if (request->input_buf != NULL)
+		str_free(&request->input_buf);
 
 	safe_memset(request->password, 0, strlen(request->password));
 	i_free(request->password);
@@ -136,10 +131,9 @@
 	/* FIXME: if we ever do some other kind of forking, this needs fixing */
 	while ((pid = waitpid(-1, &status, WNOHANG)) != 0) {
 		if (pid == -1) {
-			if (errno == ECHILD) {
-				timeout_remove(module->to_wait);
-				module->to_wait = NULL;
-			} else if (errno != EINTR)
+			if (errno == ECHILD)
+				timeout_remove(&module->to_wait);
+			else if (errno != EINTR)
 				i_error("waitpid() failed: %m");
 			return;
 		}
@@ -270,8 +264,7 @@
 		i_error("checkpassword: close() failed: %m");
         request->fd_out = -1;
 
-	io_remove(request->io_out);
-	request->io_out = NULL;
+	io_remove(&request->io_out);
 }
 
 static void
@@ -382,7 +375,7 @@
 	hash_destroy(module->clients);
 
 	if (module->to_wait != NULL)
-		timeout_remove(module->to_wait);
+		timeout_remove(&module->to_wait);
 }
 
 struct passdb_module_interface passdb_checkpassword = {
--- a/src/auth/passdb-ldap.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/passdb-ldap.c	Sat Jan 14 20:47:20 2006 +0200
@@ -95,9 +95,7 @@
 
 	passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
 
-	if (!auth_request_unref(auth_request)) {
-		/* Auth request is already aborted */
-	} else if (res != NULL) {
+	if (res != NULL) {
 		/* LDAP query returned something */
 		ret = ldap_result2error(conn->ld, res, 0);
 		if (ret != LDAP_SUCCESS) {
@@ -120,6 +118,7 @@
 	}
 
 	request->callback.verify_plain(passdb_result, auth_request);
+	auth_request_unref(&auth_request);
 	return NULL;
 }
 
@@ -164,6 +163,7 @@
 		passdb_handle_credentials(passdb_result, password, scheme,
 			ldap_request->callback.lookup_credentials,
 			auth_request);
+		auth_request_unref(&auth_request);
 		return;
 	}
 
@@ -171,6 +171,7 @@
 	if (password == NULL) {
 		ldap_request->callback.verify_plain(passdb_result,
 						    auth_request);
+		auth_request_unref(&auth_request);
 		return;
 	}
 
@@ -187,6 +188,7 @@
 	ldap_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
 					    PASSDB_RESULT_PASSWORD_MISMATCH,
 					    auth_request);
+	auth_request_unref(&auth_request);
 }
 
 static void
@@ -201,9 +203,7 @@
 
 	passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
 
-	if (!auth_request_unref(auth_request)) {
-		/* Auth request is already aborted */
-	} else if (res != NULL) {
+	if (res != NULL) {
 		ret = ldap_result2error(conn->ld, res, 0);
 		if (ret == LDAP_SUCCESS)
 			passdb_result = PASSDB_RESULT_OK;
@@ -217,6 +217,7 @@
 	}
 
 	passdb_ldap_request->callback.verify_plain(passdb_result, auth_request);
+        auth_request_unref(&auth_request);
 }
 
 static void authbind_start(struct ldap_connection *conn,
@@ -261,6 +262,7 @@
 	ldap_request->callback = handle_request_authbind;
 
         authbind_start(conn, ldap_request, ldap_get_dn(conn->ld, entry));
+	auth_request_unref(&auth_request);
 }
 
 static void ldap_lookup_pass(struct auth_request *auth_request,
@@ -428,7 +430,7 @@
 	struct ldap_passdb_module *module =
 		(struct ldap_passdb_module *)_module;
 
-	db_ldap_unref(module->conn);
+	db_ldap_unref(&module->conn);
 }
 
 struct passdb_module_interface passdb_ldap = {
--- a/src/auth/passdb-pam.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/passdb-pam.c	Sat Jan 14 20:47:20 2006 +0200
@@ -336,10 +336,10 @@
 				       "close(child input) failed: %m");
 	}
 
-	if (auth_request_unref(auth_request))
-		request->callback(result, auth_request);
+	request->callback(result, auth_request);
+	auth_request_unref(&auth_request);
 
-	io_remove(request->io);
+	io_remove(&request->io);
 	i_free(request);
 }
 
@@ -352,10 +352,9 @@
 	/* FIXME: if we ever do some other kind of forking, this needs fixing */
 	while ((pid = waitpid(-1, &status, WNOHANG)) != 0) {
 		if (pid == -1) {
-			if (errno == ECHILD) {
-				timeout_remove(module->to_wait);
-				module->to_wait = NULL;
-			} else if (errno != EINTR)
+			if (errno == ECHILD)
+				timeout_remove(&module->to_wait);
+			else if (errno != EINTR)
 				i_error("waitpid() failed: %m");
 			return;
 		}
@@ -462,7 +461,7 @@
         struct pam_passdb_module *module = (struct pam_passdb_module *)_module;
 
 	if (module->to_wait != NULL)
-		timeout_remove(module->to_wait);
+		timeout_remove(&module->to_wait);
 }
 
 struct passdb_module_interface passdb_pam = {
--- a/src/auth/passdb-passwd-file.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/passdb-passwd-file.c	Sat Jan 14 20:47:20 2006 +0200
@@ -109,7 +109,7 @@
 	struct passwd_file_passdb_module *module =
 		(struct passwd_file_passdb_module *)_module;
 
-	db_passwd_file_unref(module->pwf);
+	db_passwd_file_unref(&module->pwf);
 }
 
 struct passdb_module_interface passdb_passwd_file = {
--- a/src/auth/passdb-sql.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/passdb-sql.c	Sat Jan 14 20:47:20 2006 +0200
@@ -100,12 +100,14 @@
 		passdb_handle_credentials(passdb_result, password, scheme,
 			sql_request->callback.lookup_credentials,
 			auth_request);
+		auth_request_unref(&auth_request);
 		return;
 	}
 
 	/* verify plain */
 	if (password == NULL) {
 		sql_request->callback.verify_plain(passdb_result, auth_request);
+		auth_request_unref(&auth_request);
 		return;
 	}
 
@@ -121,6 +123,7 @@
 	sql_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
 					   PASSDB_RESULT_PASSWORD_MISMATCH,
 					   auth_request);
+	auth_request_unref(&auth_request);
 }
 
 static void sql_lookup_pass(struct passdb_sql_request *sql_request)
@@ -138,6 +141,7 @@
 	auth_request_log_debug(sql_request->auth_request, "sql",
 			       "query: %s", str_c(query));
 
+	auth_request_ref(sql_request->auth_request);
 	sql_query(module->conn->db, str_c(query),
 		  sql_query_callback, sql_request);
 }
@@ -202,7 +206,7 @@
 	struct sql_passdb_module *module =
 		(struct sql_passdb_module *)_module;
 
-	db_sql_unref(module->conn);
+	db_sql_unref(&module->conn);
 }
 
 struct passdb_module_interface passdb_sql = {
--- a/src/auth/passdb.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/passdb.c	Sat Jan 14 20:47:20 2006 +0200
@@ -192,6 +192,6 @@
 		passdb->passdb->iface.deinit(passdb->passdb);
 #ifdef HAVE_MODULES
 	if (passdb->module != NULL)
-                auth_module_close(passdb->module);
+                auth_module_close(&passdb->module);
 #endif
 }
--- a/src/auth/password-scheme.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/password-scheme.c	Sat Jan 14 20:47:20 2006 +0200
@@ -492,7 +492,7 @@
 void password_schemes_deinit(void)
 {
 #ifdef HAVE_MODULES
-	module_dir_unload(scheme_modules);
+	module_dir_unload(&scheme_modules);
 #endif
 
 	buffer_free(schemes_buf);
--- a/src/auth/userdb-ldap.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/userdb-ldap.c	Sat Jan 14 20:47:20 2006 +0200
@@ -164,6 +164,7 @@
 	}
 
 	urequest->userdb_callback(reply, auth_request);
+	auth_request_unref(&auth_request);
 }
 
 static void userdb_ldap_lookup(struct auth_request *auth_request,
@@ -178,6 +179,7 @@
 	struct userdb_ldap_request *request;
 	string_t *str;
 
+	auth_request_ref(auth_request);
 	request = p_new(auth_request->pool, struct userdb_ldap_request, 1);
 	request->request.callback = handle_request;
 	request->auth_request = auth_request;
@@ -235,7 +237,7 @@
 	struct ldap_userdb_module *module =
 		(struct ldap_userdb_module *)_module;
 
-	db_ldap_unref(module->conn);
+	db_ldap_unref(&module->conn);
 }
 
 struct userdb_module_interface userdb_ldap = {
--- a/src/auth/userdb-passwd-file.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/userdb-passwd-file.c	Sat Jan 14 20:47:20 2006 +0200
@@ -66,7 +66,7 @@
 	struct passwd_file_userdb_module *module =
 		(struct passwd_file_userdb_module *)_module;
 
-	db_passwd_file_unref(module->pwf);
+	db_passwd_file_unref(&module->pwf);
 }
 
 struct userdb_module_interface userdb_passwd_file = {
--- a/src/auth/userdb-sql.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/userdb-sql.c	Sat Jan 14 20:47:20 2006 +0200
@@ -95,6 +95,7 @@
 	}
 
 	sql_request->callback(reply, auth_request);
+	auth_request_unref(&auth_request);
 	i_free(sql_request);
 }
 
@@ -112,6 +113,7 @@
 		   auth_request_get_var_expand_table(auth_request,
 						     str_escape));
 
+	auth_request_ref(auth_request);
 	sql_request = i_new(struct userdb_sql_request, 1);
 	sql_request->callback = callback;
 	sql_request->auth_request = auth_request;
@@ -151,7 +153,7 @@
 	struct sql_userdb_module *module =
 		(struct sql_userdb_module *)_module;
 
-	db_sql_unref(module->conn);
+	db_sql_unref(&module->conn);
 }
 
 struct userdb_module_interface userdb_sql = {
--- a/src/auth/userdb.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/auth/userdb.c	Sat Jan 14 20:47:20 2006 +0200
@@ -150,6 +150,6 @@
 		userdb->userdb->iface->deinit(userdb->userdb);
 #ifdef HAVE_MODULES
 	if (userdb->module != NULL)
-                auth_module_close(userdb->module);
+                auth_module_close(&userdb->module);
 #endif
 }
--- a/src/dict/dict-cache.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/dict/dict-cache.c	Sat Jan 14 20:47:20 2006 +0200
@@ -57,7 +57,7 @@
 		return;
 
 	hash_remove(cache->dicts, uri);
-	dict_deinit(entry->dict);
+	dict_deinit(&entry->dict);
 	i_free(entry->uri);
 	i_free(entry);
 }
--- a/src/dict/dict-server.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/dict/dict-server.c	Sat Jan 14 20:47:20 2006 +0200
@@ -367,9 +367,9 @@
 		array_free(&conn->transactions);
 	}
 
-	io_remove(conn->io);
-	i_stream_unref(conn->input);
-	o_stream_unref(conn->output);
+	io_remove(&conn->io);
+	i_stream_unref(&conn->input);
+	o_stream_unref(&conn->output);
 	if (close(conn->fd) < 0)
 		i_error("close(dict client) failed: %m");
 
@@ -447,7 +447,7 @@
 	dict_cache_deinit(server->cache);
 	if (close(server->fd) < 0)
 		i_error("close(%s) failed: %m", server->path);
-	io_remove(server->io);
+	io_remove(&server->io);
 	i_free(server->path);
 	i_free(server);
 }
--- a/src/dict/main.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/dict/main.c	Sat Jan 14 20:47:20 2006 +0200
@@ -71,7 +71,7 @@
 {
 	dict_server_deinit(dict_server);
 
-	module_dir_unload(modules);
+	module_dir_unload(&modules);
 
 	dict_sql_unregister();
 	dict_client_unregister();
@@ -99,7 +99,7 @@
         io_loop_run(ioloop);
 	main_deinit();
 
-	io_loop_destroy(ioloop);
+	io_loop_destroy(&ioloop);
 	lib_deinit();
 
 	return 0;
--- a/src/imap-login/client-authenticate.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap-login/client-authenticate.c	Sat Jan 14 20:47:20 2006 +0200
@@ -168,7 +168,7 @@
 
 	/* get back to normal client input. */
 	if (client->io != NULL)
-		io_remove(client->io);
+		io_remove(&client->io);
 	client->io = io_add(client->common.fd, IO_READ, client_input, client);
 	return TRUE;
 }
@@ -201,7 +201,7 @@
 
 		/* get back to normal client input. */
 		if (client->io != NULL)
-			io_remove(client->io);
+			io_remove(&client->io);
 		client->io = io_add(client->common.fd, IO_READ,
 				    client_input, client);
 		break;
@@ -254,7 +254,7 @@
 
 	/* following input data will go to authentication */
 	if (client->io != NULL)
-		io_remove(client->io);
+		io_remove(&client->io);
 	client->io = io_add(client->common.fd, IO_READ,
 			    client_auth_input, client);
 	return 0;
@@ -308,10 +308,8 @@
 		return 1;
 
 	/* don't read any input from client until login is finished */
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
+	if (client->io != NULL)
+		io_remove(&client->io);
 
 	return 0;
 }
--- a/src/imap-login/client.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap-login/client.c	Sat Jan 14 20:47:20 2006 +0200
@@ -129,9 +129,9 @@
 	client_set_title(client);
 
 	client->common.fd = fd_ssl;
-	i_stream_unref(client->input);
-	o_stream_unref(client->output);
-	imap_parser_destroy(client->parser);
+	i_stream_unref(&client->input);
+	o_stream_unref(&client->output);
+	imap_parser_destroy(&client->parser);
 
 	/* CRLF is lost from buffer when streams are reopened. */
 	client->skip_line = FALSE;
@@ -169,10 +169,8 @@
 
 	/* remove input handler, SSL proxy gives us a new fd. we also have to
 	   remove it in case we have to wait for buffer to be flushed */
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
+	if (client->io != NULL)
+		io_remove(&client->io);
 
 	client_send_tagline(client, "OK Begin TLS negotiation now.");
 
@@ -477,10 +475,8 @@
 	if (client->common.master_tag != 0)
 		master_request_abort(&client->common);
 
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
+	if (client->io != NULL)
+		io_remove(&client->io);
 
 	if (client->common.fd != -1) {
 		net_disconnect(client->common.fd);
@@ -526,12 +522,12 @@
 	if (--client->refcount > 0)
 		return TRUE;
 
-	imap_parser_destroy(client->parser);
+	imap_parser_destroy(&client->parser);
 
 	if (client->input != NULL)
-		i_stream_unref(client->input);
+		i_stream_unref(&client->input);
 	if (client->output != NULL)
-		o_stream_unref(client->output);
+		o_stream_unref(&client->output);
 
 	i_free(client->common.virtual_user);
 	i_free(client->common.auth_mech_name);
@@ -637,5 +633,5 @@
 	clients_destroy_all();
 	hash_destroy(clients);
 
-	timeout_remove(to_idle);
+	timeout_remove(&to_idle);
 }
--- a/src/imap-login/imap-proxy.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap-login/imap-proxy.c	Sat Jan 14 20:47:20 2006 +0200
@@ -139,10 +139,8 @@
 	client->proxy_password = i_strdup(password);
 
 	/* disable input until authentication is finished */
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
+	if (client->io != NULL)
+		io_remove(&client->io);
 
 	return 0;
 }
--- a/src/imap/client.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/client.c	Sat Jan 14 20:47:20 2006 +0200
@@ -77,15 +77,15 @@
 	}
 
 	if (client->mailbox != NULL)
-		mailbox_close(client->mailbox);
+		mailbox_close(&client->mailbox);
 	namespace_deinit(client->namespaces);
 
-	imap_parser_destroy(client->parser);
+	imap_parser_destroy(&client->parser);
 	if (client->io != NULL)
-		io_remove(client->io);
+		io_remove(&client->io);
 
-	i_stream_unref(client->input);
-	o_stream_unref(client->output);
+	i_stream_unref(&client->input);
+	o_stream_unref(&client->output);
 
 	pool_unref(client->keywords.pool);
 	pool_unref(client->cmd.pool);
@@ -377,8 +377,7 @@
 
 	if (client->command_pending) {
 		/* already processing one command. wait. */
-		io_remove(client->io);
-		client->io = NULL;
+		io_remove(&client->io);
 		return;
 	}
 
@@ -495,5 +494,5 @@
 		client_destroy(my_client);
 	}
 
-	timeout_remove(to_idle);
+	timeout_remove(&to_idle);
 }
--- a/src/imap/cmd-append.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-append.c	Sat Jan 14 20:47:20 2006 +0200
@@ -105,22 +105,21 @@
 {
 	ctx->client->input_skip_line = TRUE;
 
-	io_remove(ctx->client->io);
-	ctx->client->io = NULL;
+	io_remove(&ctx->client->io);
 
-        imap_parser_destroy(ctx->save_parser);
+        imap_parser_destroy(&ctx->save_parser);
 
 	if (ctx->input != NULL)
-		i_stream_unref(ctx->input);
+		i_stream_unref(&ctx->input);
 
 	if (ctx->save_ctx != NULL)
-		mailbox_save_cancel(ctx->save_ctx);
+		mailbox_save_cancel(&ctx->save_ctx);
 
 	if (ctx->t != NULL)
-		mailbox_transaction_rollback(ctx->t);
+		mailbox_transaction_rollback(&ctx->t);
 
 	if (ctx->box != ctx->cmd->client->mailbox && ctx->box != NULL)
-		mailbox_close(ctx->box);
+		mailbox_close(&ctx->box);
 }
 
 static bool cmd_append_continue_cancel(struct client_command_context *cmd)
@@ -199,8 +198,7 @@
 			return TRUE;
 		}
 
-		ret = mailbox_transaction_commit(ctx->t, 0);
-		ctx->t = NULL;
+		ret = mailbox_transaction_commit(&ctx->t, 0);
 		if (ret < 0) {
 			client_send_storage_error(cmd, ctx->storage);
 			cmd_append_finish(ctx);
@@ -272,7 +270,7 @@
 					  ctx->input, FALSE);
 
 	if (keywords != NULL)
-		mailbox_keywords_free(ctx->t, keywords);
+		mailbox_keywords_free(ctx->t, &keywords);
 
 	client->command_pending = TRUE;
 	cmd->func = cmd_append_continue_message;
@@ -290,8 +288,7 @@
 		if (mailbox_save_continue(ctx->save_ctx) < 0) {
 			/* we still have to finish reading the message
 			   from client */
-			mailbox_save_cancel(ctx->save_ctx);
-			ctx->save_ctx = NULL;
+			mailbox_save_cancel(&ctx->save_ctx);
 		}
 	}
 
@@ -305,7 +302,7 @@
 		/* finished */
 		bool all_written = ctx->input->v_offset == ctx->msg_size;
 
-		i_stream_unref(ctx->input);
+		i_stream_unref(&ctx->input);
 		ctx->input = NULL;
 
 		if (ctx->save_ctx == NULL) {
@@ -316,8 +313,8 @@
 			/* client disconnected before it finished sending the
 			   whole message. */
 			failed = TRUE;
-			mailbox_save_cancel(ctx->save_ctx);
-		} else if (mailbox_save_finish(ctx->save_ctx, NULL) < 0) {
+			mailbox_save_cancel(&ctx->save_ctx);
+		} else if (mailbox_save_finish(&ctx->save_ctx, NULL) < 0) {
 			failed = TRUE;
 			client_send_storage_error(cmd, ctx->storage);
 		} else {
@@ -387,8 +384,7 @@
 		if (mailbox_get_status(ctx->box, STATUS_KEYWORDS,
 				       &status) < 0) {
 			client_send_storage_error(cmd, ctx->storage);
-			mailbox_close(ctx->box);
-			ctx->box = NULL;
+			mailbox_close(&ctx->box);
 		} else {
 			client_save_keywords(&client->keywords,
 					     status.keywords);
@@ -398,7 +394,7 @@
 				MAILBOX_TRANSACTION_FLAG_EXTERNAL);
 	}
 
-	io_remove(client->io);
+	io_remove(&client->io);
 	client->io = io_add(i_stream_get_fd(client->input), IO_READ,
 			    client_input, client);
 	/* append is special because we're only waiting on client input, not
--- a/src/imap/cmd-close.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-close.c	Sat Jan 14 20:47:20 2006 +0200
@@ -21,7 +21,7 @@
 			client_send_untagged_storage_error(client, storage);
 	}
 
-	if (mailbox_close(mailbox) < 0)
+	if (mailbox_close(&mailbox) < 0)
                 client_send_untagged_storage_error(client, storage);
 
 	client_send_tagline(cmd, "OK Close completed.");
--- a/src/imap/cmd-copy.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-copy.c	Sat Jan 14 20:47:20 2006 +0200
@@ -34,14 +34,14 @@
 		if (mailbox_copy(t, mail, mail_get_flags(mail),
 				 keywords, NULL) < 0)
 			ret = -1;
-		mailbox_keywords_free(t, keywords);
+		mailbox_keywords_free(t, &keywords);
 	}
-	mail_free(mail);
+	mail_free(&mail);
 
-	if (mailbox_search_deinit(search_ctx) < 0)
+	if (mailbox_search_deinit(&search_ctx) < 0)
 		ret = -1;
 
-	if (mailbox_transaction_commit(src_trans, 0) < 0)
+	if (mailbox_transaction_commit(&src_trans, 0) < 0)
 		ret = -1;
 
 	return ret;
@@ -94,15 +94,15 @@
 	ret = fetch_and_copy(t, client->mailbox, search_arg);
 
 	if (ret <= 0)
-		mailbox_transaction_rollback(t);
+		mailbox_transaction_rollback(&t);
 	else {
-		if (mailbox_transaction_commit(t, 0) < 0)
+		if (mailbox_transaction_commit(&t, 0) < 0)
 			ret = -1;
 	}
 
 	if (destbox != client->mailbox) {
 		sync_flags |= MAILBOX_SYNC_FLAG_FAST;
-		mailbox_close(destbox);
+		mailbox_close(&destbox);
 	}
 
 	if (ret > 0)
--- a/src/imap/cmd-delete.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-delete.c	Sat Jan 14 20:47:20 2006 +0200
@@ -26,7 +26,7 @@
 		storage = mailbox_get_storage(mailbox);
 		client->mailbox = NULL;
 
-		if (mailbox_close(mailbox) < 0)
+		if (mailbox_close(&mailbox) < 0)
 			client_send_untagged_storage_error(client, storage);
 	} else {
 		storage = client_find_storage(cmd, &name);
--- a/src/imap/cmd-idle.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-idle.c	Sat Jan 14 20:47:20 2006 +0200
@@ -32,14 +32,10 @@
 {
 	struct client *client = ctx->client;
 
-	if (ctx->idle_to != NULL) {
-		timeout_remove(ctx->idle_to);
-		ctx->idle_to = NULL;
-	}
-	if (ctx->keepalive_to != NULL) {
-		timeout_remove(ctx->keepalive_to);
-		ctx->keepalive_to = NULL;
-	}
+	if (ctx->idle_to != NULL)
+		timeout_remove(&ctx->idle_to);
+	if (ctx->keepalive_to != NULL)
+		timeout_remove(&ctx->keepalive_to);
 
 	if (ctx->sync_ctx != NULL) {
 		/* we're here only in connection failure cases */
@@ -54,8 +50,7 @@
 			t_strdup_printf("* %u EXPUNGE", ctx->dummy_seq));
 	}
 
-	io_remove(client->io);
-	client->io = NULL;
+	io_remove(&client->io);
 
 	if (client->mailbox != NULL)
 		mailbox_notify_changes(client->mailbox, 0, NULL, NULL);
@@ -97,8 +92,7 @@
 	if (ctx->sync_ctx != NULL) {
 		/* we're still sending output to client. wait until it's all
 		   sent so we don't lose any changes. */
-		io_remove(client->io);
-		client->io = NULL;
+		io_remove(&client->io);
 		return;
 	}
 
@@ -130,8 +124,7 @@
 	   we're about to disconnect unless it does something. send a fake
 	   EXISTS to see if it responds. it's expunged later. */
 
-	timeout_remove(ctx->idle_to);
-	ctx->idle_to = NULL;
+	timeout_remove(&ctx->idle_to);
 
 	if (ctx->sync_ctx != NULL) {
 		/* we're already syncing.. do this after it's finished */
@@ -246,7 +239,7 @@
 	}
 	client_send_line(client, "+ idling");
 
-	io_remove(client->io);
+	io_remove(&client->io);
 	client->io = io_add(i_stream_get_fd(client->input),
 			    IO_READ, idle_client_input, ctx);
 
--- a/src/imap/cmd-list.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-list.c	Sat Jan 14 20:47:20 2006 +0200
@@ -165,7 +165,7 @@
         list_namespace_inbox(client, ctx);
 	t_pop();
 
-	ret = mail_storage_mailbox_list_deinit(ctx->list_ctx);
+	ret = mail_storage_mailbox_list_deinit(&ctx->list_ctx);
 	ctx->list_ctx = NULL;
 	return ret < 0 ? -1 : 1;
 }
--- a/src/imap/cmd-logout.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-logout.c	Sat Jan 14 20:47:20 2006 +0200
@@ -15,8 +15,7 @@
 		/* this could be done at client_disconnect() as well,
 		   but eg. mbox rewrite takes a while so the waiting is
 		   better to happen before "OK" message. */
-		mailbox_close(client->mailbox);
-		client->mailbox = NULL;
+		mailbox_close(&client->mailbox);
 	}
 
 	client_send_tagline(cmd, "OK Logout completed.");
--- a/src/imap/cmd-search.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-search.c	Sat Jan 14 20:47:20 2006 +0200
@@ -25,7 +25,7 @@
 	trans = mailbox_transaction_begin(client->mailbox, 0);
 	ctx = mailbox_search_init(trans, charset, sargs, NULL);
 	if (ctx == NULL) {
-		mailbox_transaction_rollback(trans);
+		mailbox_transaction_rollback(&trans);
 		return FALSE;
 	}
 
@@ -42,11 +42,11 @@
 
 		str_printfa(str, " %u", uid ? mail->uid : mail->seq);
 	}
-	mail_free(mail);
+	mail_free(&mail);
 
-	ret = mailbox_search_deinit(ctx);
+	ret = mailbox_search_deinit(&ctx);
 
-	if (mailbox_transaction_commit(trans, 0) < 0)
+	if (mailbox_transaction_commit(&trans, 0) < 0)
 		ret = -1;
 
 	if (!first || ret == 0) {
--- a/src/imap/cmd-select.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-select.c	Sat Jan 14 20:47:20 2006 +0200
@@ -21,7 +21,7 @@
 		client->mailbox = NULL;
 
                 storage = mailbox_get_storage(box);
-		if (mailbox_close(box) < 0)
+		if (mailbox_close(&box) < 0)
 			client_send_untagged_storage_error(client, storage);
 	}
 
@@ -38,7 +38,7 @@
 
 	if (imap_sync_nonselected(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0) {
 		client_send_storage_error(cmd, storage);
-		mailbox_close(box);
+		mailbox_close(&box);
 		return TRUE;
 	}
 
@@ -47,7 +47,7 @@
 			       STATUS_UIDNEXT | STATUS_KEYWORDS,
 			       &status) < 0) {
 		client_send_storage_error(cmd, storage);
-		mailbox_close(box);
+		mailbox_close(&box);
 		return TRUE;
 	}
 
--- a/src/imap/cmd-status.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-status.c	Sat Jan 14 20:47:20 2006 +0200
@@ -71,7 +71,7 @@
 		failed = mailbox_get_status(box, items, status) < 0;
 
 	if (box != client->mailbox)
-		mailbox_close(box);
+		mailbox_close(&box);
 
 	return !failed;
 }
--- a/src/imap/cmd-store.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-store.c	Sat Jan 14 20:47:20 2006 +0200
@@ -109,18 +109,18 @@
 			}
 		}
 	}
-	mail_free(mail);
+	mail_free(&mail);
 
 	if (keywords != NULL)
-		mailbox_keywords_free(t, keywords);
+		mailbox_keywords_free(t, &keywords);
 
-	if (mailbox_search_deinit(search_ctx) < 0)
+	if (mailbox_search_deinit(&search_ctx) < 0)
 		failed = TRUE;
 
 	if (failed)
-		mailbox_transaction_rollback(t);
+		mailbox_transaction_rollback(&t);
 	else {
-		if (mailbox_transaction_commit(t, 0) < 0)
+		if (mailbox_transaction_commit(&t, 0) < 0)
 			failed = TRUE;
 	}
 
--- a/src/imap/cmd-unselect.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/cmd-unselect.c	Sat Jan 14 20:47:20 2006 +0200
@@ -15,7 +15,7 @@
 	client->mailbox = NULL;
 
 	storage = mailbox_get_storage(mailbox);
-	if (mailbox_close(mailbox) < 0)
+	if (mailbox_close(&mailbox) < 0)
 		client_send_untagged_storage_error(client, storage);
 
 	client_send_tagline(cmd, "OK Unselect completed.");
--- a/src/imap/imap-expunge.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/imap-expunge.c	Sat Jan 14 20:47:20 2006 +0200
@@ -30,18 +30,18 @@
 				break;
 			}
 		}
-		mail_free(mail);
+		mail_free(&mail);
 	}
 
-	if (mailbox_search_deinit(ctx) < 0)
+	if (mailbox_search_deinit(&ctx) < 0)
 		return FALSE;
 
 	if (failed)
-		mailbox_transaction_rollback(t);
+		mailbox_transaction_rollback(&t);
 	else {
 		flags = MAILBOX_SYNC_FLAG_FULL_READ |
 			MAILBOX_SYNC_FLAG_FULL_WRITE;
-		if (mailbox_transaction_commit(t, flags) < 0)
+		if (mailbox_transaction_commit(&t, flags) < 0)
 			failed = TRUE;
 	}
 
--- a/src/imap/imap-fetch-body.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/imap-fetch-body.c	Sat Jan 14 20:47:20 2006 +0200
@@ -260,7 +260,7 @@
 		input = i_stream_create_limit(default_pool, ctx->cur_input,
 					      ctx->cur_input->v_offset,
 					      ctx->cur_size);
-		i_stream_unref(ctx->cur_input);
+		i_stream_unref(&ctx->cur_input);
 		ctx->cur_input = input;
 
 		ctx->cont_handler = fetch_stream_send_direct;
@@ -372,7 +372,7 @@
 		return -1;
 	}
 
-	i_stream_unref(ctx->cur_input);
+	i_stream_unref(&ctx->cur_input);
 	ctx->cur_input = input;
 	ctx->update_partial = FALSE;
 
--- a/src/imap/imap-fetch.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/imap-fetch.c	Sat Jan 14 20:47:20 2006 +0200
@@ -236,10 +236,8 @@
 		}
 
 		if (ctx->cur_mail == NULL) {
-			if (ctx->cur_input != NULL) {
-				i_stream_unref(ctx->cur_input);
-                                ctx->cur_input = NULL;
-			}
+			if (ctx->cur_input != NULL)
+				i_stream_unref(&ctx->cur_input);
 
 			if (mailbox_search_next(ctx->search_ctx,
 						ctx->mail) <= 0)
@@ -304,33 +302,31 @@
 
 int imap_fetch_deinit(struct imap_fetch_context *ctx)
 {
-	str_free(ctx->cur_str);
+	str_free(&ctx->cur_str);
 
 	if (!ctx->line_finished) {
 		if (o_stream_send(ctx->client->output, ")\r\n", 3) < 0)
 			ctx->failed = TRUE;
 	}
 
-	if (ctx->cur_input != NULL) {
-		i_stream_unref(ctx->cur_input);
-		ctx->cur_input = NULL;
-	}
+	if (ctx->cur_input != NULL)
+		i_stream_unref(&ctx->cur_input);
 
 	if (ctx->mail != NULL)
-		mail_free(ctx->mail);
+		mail_free(&ctx->mail);
 
 	if (ctx->search_ctx != NULL) {
-		if (mailbox_search_deinit(ctx->search_ctx) < 0)
+		if (mailbox_search_deinit(&ctx->search_ctx) < 0)
 			ctx->failed = TRUE;
 	}
 	if (ctx->all_headers_ctx != NULL)
-		mailbox_header_lookup_deinit(ctx->all_headers_ctx);
+		mailbox_header_lookup_deinit(&ctx->all_headers_ctx);
 
 	if (ctx->trans != NULL) {
 		if (ctx->failed)
-			mailbox_transaction_rollback(ctx->trans);
+			mailbox_transaction_rollback(&ctx->trans);
 		else {
-			if (mailbox_transaction_commit(ctx->trans, 0) < 0)
+			if (mailbox_transaction_commit(&ctx->trans, 0) < 0)
 				ctx->failed = TRUE;
 		}
 	}
--- a/src/imap/imap-sort.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/imap-sort.c	Sat Jan 14 20:47:20 2006 +0200
@@ -248,12 +248,12 @@
 		mail_sort_input(ctx, mail);
 
 	mail_sort_flush(ctx);
-	ret = mailbox_search_deinit(ctx->search_ctx);
+	ret = mailbox_search_deinit(&ctx->search_ctx);
 
-	mail_free(mail);
-	mail_free(ctx->other_mail);
+	mail_free(&mail);
+	mail_free(&ctx->other_mail);
 
-	if (mailbox_transaction_commit(ctx->t, 0) < 0)
+	if (mailbox_transaction_commit(&ctx->t, 0) < 0)
 		ret = -1;
 
 	if (ctx->written || ret == 0) {
@@ -263,7 +263,7 @@
 	}
 
 	if (headers_ctx != NULL)
-		mailbox_header_lookup_deinit(headers_ctx);
+		mailbox_header_lookup_deinit(&headers_ctx);
         mail_sort_deinit(ctx);
 	return ret;
 }
--- a/src/imap/imap-sync.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/imap-sync.c	Sat Jan 14 20:47:20 2006 +0200
@@ -61,15 +61,15 @@
 {
 	struct mailbox_status status;
 
-	mail_free(ctx->mail);
+	mail_free(&ctx->mail);
 
-	if (mailbox_sync_deinit(ctx->sync_ctx, &status) < 0 || ctx->failed) {
-		mailbox_transaction_rollback(ctx->t);
+	if (mailbox_sync_deinit(&ctx->sync_ctx, &status) < 0 || ctx->failed) {
+		mailbox_transaction_rollback(&ctx->t);
 		i_free(ctx);
 		return -1;
 	}
 
-	mailbox_transaction_commit(ctx->t, 0);
+	mailbox_transaction_commit(&ctx->t, 0);
 
 	t_push();
 
@@ -183,7 +183,7 @@
 	ctx = mailbox_sync_init(box, flags);
 	while (mailbox_sync_next(ctx, &sync_rec) > 0)
 		;
-	return mailbox_sync_deinit(ctx, &status);
+	return mailbox_sync_deinit(&ctx, &status);
 }
 
 static bool cmd_sync_continue(struct client_command_context *cmd)
--- a/src/imap/imap-thread.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/imap-thread.c	Sat Jan 14 20:47:20 2006 +0200
@@ -142,17 +142,17 @@
 	while (mailbox_search_next(ctx->search_ctx, mail) > 0)
 		mail_thread_input(ctx, mail);
 
-	mail_free(mail);
+	mail_free(&mail);
 
 	o_stream_send_str(client->output, "* THREAD");
 	mail_thread_finish(ctx);
 	o_stream_send_str(client->output, "\r\n");
 
-	ret = mailbox_search_deinit(ctx->search_ctx);
-	if (mailbox_transaction_commit(ctx->t, 0) < 0)
+	ret = mailbox_search_deinit(&ctx->search_ctx);
+	if (mailbox_transaction_commit(&ctx->t, 0) < 0)
 		ret = -1;
 
-	mailbox_header_lookup_deinit(headers_ctx);
+	mailbox_header_lookup_deinit(&headers_ctx);
         mail_thread_deinit(ctx);
 	return ret;
 }
@@ -708,8 +708,8 @@
 		}
 	}
 
-	mail_free(ctx->mail);
-	mailbox_header_lookup_deinit(headers_ctx);
+	mail_free(&ctx->mail);
+	mailbox_header_lookup_deinit(&headers_ctx);
 }
 
 static void reset_children_parent(struct node *parent)
--- a/src/imap/main.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/main.c	Sat Jan 14 20:47:20 2006 +0200
@@ -198,7 +198,7 @@
 
 static void main_deinit(void)
 {
-	module_dir_unload(modules);
+	module_dir_unload(&modules);
 
 	commands_deinit();
 	clients_deinit();
@@ -207,7 +207,7 @@
 	random_deinit();
 	pool_unref(namespace_pool);
 
-	str_free(capability_string);
+	str_free(&capability_string);
 
 	lib_signals_deinit();
 	closelog();
@@ -238,7 +238,7 @@
         io_loop_run(ioloop);
 	main_deinit();
 
-	io_loop_destroy(ioloop);
+	io_loop_destroy(&ioloop);
 	lib_deinit();
 
 	return 0;
--- a/src/imap/namespace.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/imap/namespace.c	Sat Jan 14 20:47:20 2006 +0200
@@ -173,7 +173,7 @@
 void namespace_deinit(struct namespace *namespaces)
 {
 	while (namespaces != NULL) {
-		mail_storage_destroy(namespaces->storage);
+		mail_storage_destroy(&namespaces->storage);
 		namespaces = namespaces->next;
 	}
 }
--- a/src/lib-auth/auth-client.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-auth/auth-client.c	Sat Jan 14 20:47:20 2006 +0200
@@ -34,12 +34,15 @@
 	return client;
 }
 
-void auth_client_free(struct auth_client *client)
+void auth_client_free(struct auth_client **_client)
 {
+	struct auth_client *client = *_client;
 	struct auth_server_connection *next;
 	struct auth_mech_desc *mech;
 	size_t i, size;
 
+	*_client = NULL;
+
 	mech = buffer_get_modifyable_data(client->available_auth_mechs, &size);
 	size /= sizeof(*mech);
 	for (i = 0; i < size; i++)
@@ -48,12 +51,12 @@
 
 	while (client->connections != NULL) {
 		next = client->connections->next;
-		auth_server_connection_destroy(client->connections, FALSE);
+		auth_server_connection_destroy(&client->connections, FALSE);
 		client->connections = next;
 	}
 
 	if (client->to_reconnect != NULL)
-		timeout_remove(client->to_reconnect);
+		timeout_remove(&client->to_reconnect);
 	i_free(client->socket_paths);
 	i_free(client);
 }
@@ -189,10 +192,8 @@
 			client->to_reconnect =
 				timeout_add(5000, reconnect_timeout, client);
 		}
-	} else if (client->to_reconnect != NULL) {
-		timeout_remove(client->to_reconnect);
-		client->to_reconnect = NULL;
-	}
+	} else if (client->to_reconnect != NULL)
+		timeout_remove(&client->to_reconnect);
 
 	if (client->connect_notify_callback != NULL) {
 		client->connect_notify_callback(client,
--- a/src/lib-auth/auth-client.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-auth/auth-client.h	Sat Jan 14 20:47:20 2006 +0200
@@ -42,7 +42,7 @@
 
 /* Create new authentication client. */
 struct auth_client *auth_client_new(unsigned int client_pid);
-void auth_client_free(struct auth_client *client);
+void auth_client_free(struct auth_client **client);
 
 bool auth_client_is_connected(struct auth_client *client);
 void auth_client_set_connect_notify(struct auth_client *client,
--- a/src/lib-auth/auth-server-connection.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-auth/auth-server-connection.c	Sat Jan 14 20:47:20 2006 +0200
@@ -135,13 +135,13 @@
 		return;
 	case -1:
 		/* disconnected */
-		auth_server_connection_destroy(conn, TRUE);
+		auth_server_connection_destroy(&conn, TRUE);
 		return;
 	case -2:
 		/* buffer full - can't happen unless auth is buggy */
 		i_error("BUG: Auth server sent us more than %d bytes of data",
 			AUTH_CLIENT_MAX_LINE_LENGTH);
-		auth_server_connection_destroy(conn, FALSE);
+		auth_server_connection_destroy(&conn, FALSE);
 		return;
 	}
 
@@ -156,7 +156,7 @@
 		    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION) {
 			i_error("Authentication server not compatible with "
 				"this client (mixed old and new binaries?)");
-			auth_server_connection_destroy(conn, FALSE);
+			auth_server_connection_destroy(&conn, FALSE);
 			return;
 		}
 		conn->version_received = TRUE;
@@ -184,7 +184,7 @@
 		}
 
 		if (!ret) {
-			auth_server_connection_destroy(conn, FALSE);
+			auth_server_connection_destroy(&conn, FALSE);
 			break;
 		}
 	}
@@ -249,18 +249,21 @@
 	if (o_stream_send_str(conn->output, handshake) < 0) {
 		errno = conn->output->stream_errno;
 		i_warning("Error sending handshake to auth server: %m");
-		auth_server_connection_destroy(conn, TRUE);
+		auth_server_connection_destroy(&conn, TRUE);
 		return NULL;
 	}
 	return conn;
 }
 
-void auth_server_connection_destroy(struct auth_server_connection *conn,
+void auth_server_connection_destroy(struct auth_server_connection **_conn,
 				    bool reconnect)
 {
+        struct auth_server_connection *conn = *_conn;
 	struct auth_client *client = conn->client;
 	struct auth_server_connection **pos;
 
+	*_conn = NULL;
+
 	if (conn->fd == -1)
 		return;
 
@@ -279,10 +282,8 @@
 		client->ext_input_remove(conn->ext_input_io);
 		conn->ext_input_io = NULL;
 	}
-	if (conn->io != NULL) {
-		io_remove(conn->io);
-		conn->io = NULL;
-	}
+	if (conn->io != NULL)
+		io_remove(&conn->io);
 
 	i_stream_close(conn->input);
 	o_stream_close(conn->output);
@@ -312,8 +313,8 @@
 	hash_destroy(conn->requests);
 	buffer_free(conn->auth_mechs_buf);
 
-	i_stream_unref(conn->input);
-	o_stream_unref(conn->output);
+	i_stream_unref(&conn->input);
+	o_stream_unref(&conn->output);
 	pool_unref(conn->pool);
 }
 
--- a/src/lib-auth/auth-server-connection.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-auth/auth-server-connection.h	Sat Jan 14 20:47:20 2006 +0200
@@ -54,7 +54,7 @@
 
 struct auth_server_connection *
 auth_server_connection_new(struct auth_client *client, const char *path);
-void auth_server_connection_destroy(struct auth_server_connection *conn,
+void auth_server_connection_destroy(struct auth_server_connection **conn,
 				    bool reconnect);
 
 struct auth_server_connection *
--- a/src/lib-auth/auth-server-request.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-auth/auth-server-request.c	Sat Jan 14 20:47:20 2006 +0200
@@ -117,7 +117,7 @@
 	if (ret < 0) {
 		errno = conn->output->stream_errno;
 		i_warning("Error sending request to auth server: %m");
-		auth_server_connection_destroy(conn, TRUE);
+		auth_server_connection_destroy(&conn, TRUE);
 		return FALSE;
 	}
 
@@ -144,7 +144,7 @@
 	if (o_stream_sendv(conn->output, iov, 3) < 0) {
 		errno = conn->output->stream_errno;
 		i_warning("Error sending continue request to auth server: %m");
-		auth_server_connection_destroy(conn, TRUE);
+		auth_server_connection_destroy(&conn, TRUE);
 	}
 }
 
--- a/src/lib-charset/charset-iconv.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-charset/charset-iconv.c	Sat Jan 14 20:47:20 2006 +0200
@@ -48,8 +48,12 @@
 	return t;
 }
 
-void charset_to_utf8_end(struct charset_translation *t)
+void charset_to_utf8_end(struct charset_translation **_t)
 {
+	struct charset_translation *t = *_t;
+
+	*_t = NULL;
+
 	if (t->cd != (iconv_t)-1)
 		iconv_close(t->cd);
 	i_free(t);
--- a/src/lib-charset/charset-utf8.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-charset/charset-utf8.c	Sat Jan 14 20:47:20 2006 +0200
@@ -61,7 +61,7 @@
 	return NULL;
 }
 
-void charset_to_utf8_end(struct charset_translation *t __attr_unused__)
+void charset_to_utf8_end(struct charset_translation **t __attr_unused__)
 {
 }
 
--- a/src/lib-charset/charset-utf8.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-charset/charset-utf8.h	Sat Jan 14 20:47:20 2006 +0200
@@ -12,7 +12,7 @@
 struct charset_translation *charset_to_utf8_begin(const char *charset,
 						  bool *unknown_charset);
 
-void charset_to_utf8_end(struct charset_translation *t);
+void charset_to_utf8_end(struct charset_translation **t);
 
 void charset_to_utf8_reset(struct charset_translation *t);
 
--- a/src/lib-dict/dict-client.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-dict/dict-client.c	Sat Jan 14 20:47:20 2006 +0200
@@ -208,14 +208,10 @@
 	dict->connect_counter++;
 	dict->handshaked = FALSE;
 
-	if (dict->input != NULL) {
-		i_stream_unref(dict->input);
-		dict->input = NULL;
-	}
-	if (dict->output != NULL) {
-		o_stream_unref(dict->output);
-		dict->output = NULL;
-	}
+	if (dict->input != NULL)
+		i_stream_unref(&dict->input);
+	if (dict->output != NULL)
+		o_stream_unref(&dict->output);
 
 	if (dict->fd != -1) {
 		if (close(dict->fd) < 0)
--- a/src/lib-dict/dict-sql.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-dict/dict-sql.c	Sat Jan 14 20:47:20 2006 +0200
@@ -69,7 +69,7 @@
 
 		t_pop();
 	}
-	i_stream_unref(input);
+	i_stream_unref(&input);
 	(void)close(fd);
 
 	if (dict->connect_string == NULL) {
@@ -117,7 +117,7 @@
 {
 	struct sql_dict *dict = (struct sql_dict *)_dict;
 
-	sql_deinit(dict->db);
+	sql_deinit(&dict->db);
 	pool_unref(dict->pool);
 }
 
@@ -217,7 +217,7 @@
 	const char *error;
 	int ret;
 
-	ret = sql_transaction_commit_s(ctx->sql_ctx, &error);
+	ret = sql_transaction_commit_s(&ctx->sql_ctx, &error);
 	if (ret < 0)
 		i_error("sql dict: commit failed: %s", error);
 	i_free(ctx);
@@ -229,7 +229,7 @@
 	struct sql_dict_transaction_context *ctx =
 		(struct sql_dict_transaction_context *)_ctx;
 
-	sql_transaction_rollback(ctx->sql_ctx);
+	sql_transaction_rollback(&ctx->sql_ctx);
 	i_free(ctx);
 }
 
--- a/src/lib-dict/dict.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-dict/dict.c	Sat Jan 14 20:47:20 2006 +0200
@@ -71,8 +71,11 @@
 	return dict->v.init(dict, p+1);
 }
 
-void dict_deinit(struct dict *dict)
+void dict_deinit(struct dict **_dict)
 {
+	struct dict *dict = *_dict;
+
+	*_dict = NULL;
 	dict->v.deinit(dict);
 }
 
--- a/src/lib-dict/dict.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-dict/dict.h	Sat Jan 14 20:47:20 2006 +0200
@@ -13,7 +13,7 @@
    If URI is invalid, returns NULL. */
 struct dict *dict_init(const char *uri);
 /* Close dictionary. */
-void dict_deinit(struct dict *dict);
+void dict_deinit(struct dict **dict);
 
 /* Lookup value for key. Set it to NULL if it's not found.
    Returns 1 if found, 0 if not found and -1 if lookup failed. */
--- a/src/lib-imap/imap-base-subject.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-imap/imap-base-subject.c	Sat Jan 14 20:47:20 2006 +0200
@@ -25,7 +25,7 @@
 		t = charset_to_utf8_begin(charset, NULL);
 		if (t != NULL) {
 			(void)charset_to_ucase_utf8(t, data, &size, buf);
-                        charset_to_utf8_end(t);
+                        charset_to_utf8_end(&t);
 		}
 	}
 
--- a/src/lib-imap/imap-bodystructure.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-imap/imap-bodystructure.c	Sat Jan 14 20:47:20 2006 +0200
@@ -177,7 +177,7 @@
 			}
 			d->content_type_params =
 				p_strdup_empty(pool, str_c(d->str));
-			str_free(d->str);
+			str_free(&d->str);
 		}
 		if (strcasecmp(name, "Transfer-Encoding") == 0 &&
 		    d->content_transfer_encoding == NULL) {
@@ -209,7 +209,7 @@
 						     parse_save_params_list, d);
 			d->content_disposition_params =
 				p_strdup_empty(pool, str_c(d->str));
-			str_free(d->str);
+			str_free(&d->str);
 		}
 		break;
 	}
@@ -684,7 +684,7 @@
 	if (!ret)
 		i_error("Error parsing IMAP bodystructure: %s", bodystructure);
 
-	imap_parser_destroy(parser);
-	i_stream_unref(input);
+	imap_parser_destroy(&parser);
+	i_stream_unref(&input);
 	return ret;
 }
--- a/src/lib-imap/imap-envelope.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-imap/imap-envelope.c	Sat Jan 14 20:47:20 2006 +0200
@@ -396,7 +396,7 @@
 		ret = FALSE;
 	}
 
-	imap_parser_destroy(parser);
-	i_stream_unref(input);
+	imap_parser_destroy(&parser);
+	i_stream_unref(&input);
 	return ret;
 }
--- a/src/lib-imap/imap-match.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-imap/imap-match.c	Sat Jan 14 20:47:20 2006 +0200
@@ -86,9 +86,10 @@
 	return glob;
 }
 
-void imap_match_deinit(struct imap_match_glob *glob)
+void imap_match_deinit(struct imap_match_glob **glob)
 {
-	p_free(glob->pool, glob);
+	p_free((*glob)->pool, *glob);
+	*glob = NULL;
 }
 
 static inline bool cmp_chr(const struct imap_match_glob *glob,
--- a/src/lib-imap/imap-match.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-imap/imap-match.h	Sat Jan 14 20:47:20 2006 +0200
@@ -16,7 +16,7 @@
 struct imap_match_glob *
 imap_match_init(pool_t pool, const char *mask, bool inboxcase, char separator);
 
-void imap_match_deinit(struct imap_match_glob *glob);
+void imap_match_deinit(struct imap_match_glob **glob);
 
 enum imap_match_result
 imap_match(struct imap_match_glob *glob, const char *data);
--- a/src/lib-imap/imap-parser.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-imap/imap-parser.c	Sat Jan 14 20:47:20 2006 +0200
@@ -82,10 +82,11 @@
 	return parser;
 }
 
-void imap_parser_destroy(struct imap_parser *parser)
+void imap_parser_destroy(struct imap_parser **parser)
 {
-	pool_unref(parser->pool);
-	i_free(parser);
+	pool_unref((*parser)->pool);
+	i_free(*parser);
+	*parser = NULL;
 }
 
 void imap_parser_reset(struct imap_parser *parser)
--- a/src/lib-imap/imap-parser.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-imap/imap-parser.h	Sat Jan 14 20:47:20 2006 +0200
@@ -86,7 +86,7 @@
 struct imap_parser *
 imap_parser_create(struct istream *input, struct ostream *output,
 		   size_t max_line_size);
-void imap_parser_destroy(struct imap_parser *parser);
+void imap_parser_destroy(struct imap_parser **parser);
 
 /* Reset the parser to initial state. */
 void imap_parser_reset(struct imap_parser *parser);
--- a/src/lib-index/mail-cache-compress.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-cache-compress.c	Sat Jan 14 20:47:20 2006 +0200
@@ -215,8 +215,8 @@
 	if (o_stream_flush(output) < 0) {
 		errno = output->stream_errno;
 		mail_cache_set_syscall_error(cache, "o_stream_flush()");
-		(void)mail_index_transaction_rollback(t);
-		o_stream_unref(output);
+		(void)mail_index_transaction_rollback(&t);
+		o_stream_unref(&output);
 		return -1;
 	}
 
@@ -225,15 +225,15 @@
 		(void)file_set_size(fd, MAIL_CACHE_INITIAL_SIZE);
 	}
 
-	o_stream_unref(output);
+	o_stream_unref(&output);
 
 	if (fdatasync(fd) < 0) {
 		mail_cache_set_syscall_error(cache, "fdatasync()");
-		(void)mail_index_transaction_rollback(t);
+		(void)mail_index_transaction_rollback(&t);
 		return -1;
 	}
 
-	return mail_index_transaction_commit(t, &seq, &offset);
+	return mail_index_transaction_commit(&t, &seq, &offset);
 }
 
 static int mail_cache_compress_locked(struct mail_cache *cache,
--- a/src/lib-index/mail-cache.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-cache.c	Sat Jan 14 20:47:20 2006 +0200
@@ -104,11 +104,11 @@
 		   happen often so we'll just mark cache to be compressed
 		   later which fixes this. */
 		cache->need_compress = TRUE;
-		mail_index_view_close(view);
+		mail_index_view_close(&view);
 		return 0;
 	}
 
-	mail_index_view_close(view);
+	mail_index_view_close(&view);
 	return 1;
 }
 
@@ -326,14 +326,16 @@
 	return cache;
 }
 
-void mail_cache_free(struct mail_cache *cache)
+void mail_cache_free(struct mail_cache **_cache)
 {
+	struct mail_cache *cache = *_cache;
+
+	*_cache = NULL;
 	if (cache->file_cache != NULL) {
 		mail_index_unregister_sync_lost_handler(cache->index,
 			mail_cache_sync_lost_handler);
 
-		file_cache_free(cache->file_cache);
-		cache->file_cache = NULL;
+		file_cache_free(&cache->file_cache);
 	}
 
 	mail_index_unregister_expunge_handler(cache->index, cache->ext_id);
@@ -381,14 +383,14 @@
 	ext = mail_index_view_get_ext(view, cache->ext_id);
 	if (ext == NULL) {
 		/* cache not used */
-		mail_index_view_close(view);
+		mail_index_view_close(&view);
 		return 0;
 	}
 
 	if (cache->hdr->file_seq != ext->reset_id) {
 		/* we want the latest cache file */
 		if ((ret = mail_cache_reopen(cache)) <= 0) {
-			mail_index_view_close(view);
+			mail_index_view_close(&view);
 			return ret;
 		}
 	}
@@ -425,7 +427,7 @@
 		}
 	}
 
-	mail_index_view_close(view);
+	mail_index_view_close(&view);
 	i_assert((ret <= 0 && !cache->locked) || (ret > 0 && cache->locked));
 	return ret;
 }
@@ -525,7 +527,7 @@
                 (void)mail_cache_header_fields_update(view->cache);
 
 	if (view->trans_view != NULL)
-		mail_index_view_close(view->trans_view);
+		mail_index_view_close(&view->trans_view);
 
 	array_free(&view->tmp_offsets);
 	buffer_free(view->cached_exists_buf);
--- a/src/lib-index/mail-cache.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-cache.h	Sat Jan 14 20:47:20 2006 +0200
@@ -40,7 +40,7 @@
 
 struct mail_cache *mail_cache_open_or_create(struct mail_index *index);
 struct mail_cache *mail_cache_create(struct mail_index *index);
-void mail_cache_free(struct mail_cache *cache);
+void mail_cache_free(struct mail_cache **cache);
 
 /* Register fields. fields[].idx is updated to contain field index. */
 void mail_cache_register_fields(struct mail_cache *cache,
--- a/src/lib-index/mail-index-private.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index-private.h	Sat Jan 14 20:47:20 2006 +0200
@@ -229,7 +229,7 @@
 int mail_index_get_latest_header(struct mail_index *index,
 				 struct mail_index_header *hdr_r);
 /* Unreference given mapping and unmap it if it's dropped to zero. */
-void mail_index_unmap(struct mail_index *index, struct mail_index_map *map);
+void mail_index_unmap(struct mail_index *index, struct mail_index_map **map);
 struct mail_index_map *
 mail_index_map_clone(struct mail_index_map *map, uint32_t new_record_size);
 
--- a/src/lib-index/mail-index-sync-update.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index-sync-update.c	Sat Jan 14 20:47:20 2006 +0200
@@ -20,10 +20,10 @@
 	/* if map still exists after this, it's only in views. */
 	view->map->write_to_disk = FALSE;
 
-	mail_index_unmap(view->index, view->map);
+	mail_index_unmap(view->index, &view->map);
 	view->map = map;
 	view->map->refcount++;
-	mail_index_unmap(view->index, view->index->map);
+	mail_index_unmap(view->index, &view->index->map);
 	view->index->map = map;
 	view->index->hdr = &map->hdr;
 
@@ -625,7 +625,7 @@
 	}
 	i_assert(map->hdr.base_header_size >= sizeof(map->hdr));
 
-	mail_index_unmap(index, view->map);
+	mail_index_unmap(index, &view->map);
 	view->map = map;
 	view->map->refcount++;
 
@@ -681,7 +681,7 @@
 			}
 			if (map != index->map) {
 				map = index->map;
-				mail_index_unmap(view->index, view->map);
+				mail_index_unmap(view->index, &view->map);
 				view->map = map;
 				view->map->refcount++;
 			}
--- a/src/lib-index/mail-index-sync.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index-sync.c	Sat Jan 14 20:47:20 2006 +0200
@@ -77,7 +77,7 @@
 		}
 	}
 
-	mail_index_keywords_free(keywords);
+	mail_index_keywords_free(&keywords);
 	t_pop();
 }
 
@@ -95,7 +95,7 @@
 						   MODIFY_REPLACE, keywords);
 		}
 	}
-	mail_index_keywords_free(keywords);
+	mail_index_keywords_free(&keywords);
 }
 
 static void mail_index_sync_add_append(struct mail_index_sync_ctx *ctx)
@@ -410,12 +410,12 @@
 
 	dummy_view = mail_index_dummy_view_open(index);
 	ctx->trans = mail_index_transaction_begin(dummy_view, FALSE, TRUE);
-	mail_index_view_close(dummy_view);
+	mail_index_view_close(&dummy_view);
 
 	if (mail_index_sync_set_log_view(ctx->view,
 					 index->hdr->log_file_seq,
 					 index->hdr->log_file_int_offset) < 0) {
-                mail_index_sync_rollback(ctx);
+                mail_index_sync_rollback(&ctx);
 		return -1;
 	}
 
@@ -433,11 +433,11 @@
 	if (seq != index->hdr->log_file_seq ||
 	    offset != index->hdr->log_file_ext_offset) {
 		if (mail_index_sync_commit_external(ctx) < 0) {
-			mail_index_sync_rollback(ctx);
+			mail_index_sync_rollback(&ctx);
 			return -1;
 		}
 
-		mail_index_view_close(ctx->view);
+		mail_index_view_close(&ctx->view);
 		ctx->view = mail_index_view_open(index);
 
 		if (mail_index_sync_set_log_view(ctx->view,
@@ -449,7 +449,7 @@
 	/* we need to have all the transactions sorted to optimize
 	   caller's mailbox access patterns */
 	if (mail_index_sync_read_and_sort(ctx, &seen_external) < 0) {
-                mail_index_sync_rollback(ctx);
+                mail_index_sync_rollback(&ctx);
 		return -1;
 	}
 
@@ -618,20 +618,24 @@
 		sync_list[i].idx = 0;
 }
 
-static void mail_index_sync_end(struct mail_index_sync_ctx *ctx)
+static void mail_index_sync_end(struct mail_index_sync_ctx **_ctx)
 {
+        struct mail_index_sync_ctx *ctx = *_ctx;
+
+	*_ctx = NULL;
 	mail_index_unlock(ctx->index, ctx->lock_id);
 
 	i_assert(!ctx->index->map->write_to_disk);
 	mail_transaction_log_sync_unlock(ctx->index->log);
 
-	mail_index_view_close(ctx->view);
-	mail_index_transaction_rollback(ctx->trans);
+	mail_index_view_close(&ctx->view);
+	mail_index_transaction_rollback(&ctx->trans);
 	i_free(ctx);
 }
 
-int mail_index_sync_commit(struct mail_index_sync_ctx *ctx)
+int mail_index_sync_commit(struct mail_index_sync_ctx **_ctx)
 {
+        struct mail_index_sync_ctx *ctx = *_ctx;
 	struct mail_index *index = ctx->index;
 	const struct mail_index_header *hdr;
 	uint32_t seq;
@@ -675,11 +679,11 @@
 	index->sync_log_file_seq = index->map->hdr.log_file_seq;
 	index->sync_log_file_offset = index->map->hdr.log_file_int_offset;
 
-	mail_index_sync_end(ctx);
+	mail_index_sync_end(_ctx);
 	return ret;
 }
 
-void mail_index_sync_rollback(struct mail_index_sync_ctx *ctx)
+void mail_index_sync_rollback(struct mail_index_sync_ctx **ctx)
 {
 	mail_index_sync_end(ctx);
 }
--- a/src/lib-index/mail-index-transaction-private.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index-transaction-private.h	Sat Jan 14 20:47:20 2006 +0200
@@ -47,7 +47,7 @@
 mail_index_transaction_lookup(struct mail_index_transaction *t, uint32_t seq);
 
 void mail_index_transaction_ref(struct mail_index_transaction *t);
-void mail_index_transaction_unref(struct mail_index_transaction *t);
+void mail_index_transaction_unref(struct mail_index_transaction **t);
 
 bool mail_index_seq_array_lookup(const array_t *buffer, uint32_t seq,
 				 unsigned int *idx_r);
--- a/src/lib-index/mail-index-transaction-view.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index-transaction-view.c	Sat Jan 14 20:47:20 2006 +0200
@@ -18,7 +18,7 @@
 	struct mail_index_view_transaction *tview =
 		(struct mail_index_view_transaction *)view;
 
-	mail_index_transaction_unref(tview->t);
+	mail_index_transaction_unref(&tview->t);
 	tview->parent->close(view);
 }
 
--- a/src/lib-index/mail-index-transaction.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index-transaction.c	Sat Jan 14 20:47:20 2006 +0200
@@ -84,7 +84,7 @@
 		array_free(&t->ext_resets);
 
 	mail_index_view_transaction_unref(t->view);
-	mail_index_view_close(t->view);
+	mail_index_view_close(&t->view);
 	i_free(t);
 }
 
@@ -93,8 +93,11 @@
 	t->refcount++;
 }
 
-void mail_index_transaction_unref(struct mail_index_transaction *t)
+void mail_index_transaction_unref(struct mail_index_transaction **_t)
 {
+	struct mail_index_transaction *t = *_t;
+
+	*_t = NULL;
 	if (--t->refcount == 0)
 		mail_index_transaction_free(t);
 }
@@ -194,14 +197,15 @@
 		rec1->uid > rec2->uid ? 1 : 0;
 }
 
-int mail_index_transaction_commit(struct mail_index_transaction *t,
+int mail_index_transaction_commit(struct mail_index_transaction **_t,
 				  uint32_t *log_file_seq_r,
 				  uoff_t *log_file_offset_r)
 {
+	struct mail_index_transaction *t = *_t;
 	int ret;
 
 	if (mail_index_view_is_inconsistent(t->view)) {
-		mail_index_transaction_rollback(t);
+		mail_index_transaction_rollback(_t);
 		return -1;
 	}
 
@@ -225,17 +229,19 @@
 						  log_file_offset_r);
 	}
 
-	mail_index_transaction_unref(t);
+	mail_index_transaction_unref(_t);
 	return ret;
 }
 
-void mail_index_transaction_rollback(struct mail_index_transaction *t)
+void mail_index_transaction_rollback(struct mail_index_transaction **_t)
 {
+	struct mail_index_transaction *t = *_t;
+
 	if (t->cache_trans_ctx != NULL) {
 		mail_cache_transaction_rollback(t->cache_trans_ctx);
                 t->cache_trans_ctx = NULL;
 	}
-        mail_index_transaction_unref(t);
+        mail_index_transaction_unref(_t);
 }
 
 struct mail_index_record *
@@ -800,9 +806,10 @@
 	return k;
 }
 
-void mail_index_keywords_free(struct mail_keywords *keywords)
+void mail_index_keywords_free(struct mail_keywords **keywords)
 {
-	i_free(keywords);
+	i_free(*keywords);
+	*keywords = NULL;
 }
 
 void mail_index_update_keywords(struct mail_index_transaction *t, uint32_t seq,
--- a/src/lib-index/mail-index-view-sync.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index-view-sync.c	Sat Jan 14 20:47:20 2006 +0200
@@ -259,7 +259,7 @@
 		map = mail_index_map_clone(view->map,
 					   view->map->hdr.record_size);
 		view->map->records_count = old_records_count;
-		mail_index_unmap(view->index, view->map);
+		mail_index_unmap(view->index, &view->map);
 		view->map = map;
 
 		if (ctx->sync_map_update) {
@@ -522,12 +522,14 @@
 		array_delete(&view->log_syncs, 0, i);
 }
 
-void mail_index_view_sync_end(struct mail_index_view_sync_ctx *ctx)
+void mail_index_view_sync_end(struct mail_index_view_sync_ctx **_ctx)
 {
+        struct mail_index_view_sync_ctx *ctx = *_ctx;
         struct mail_index_view *view = ctx->view;
 
 	i_assert(view->syncing);
 
+	*_ctx = NULL;
 	if (ctx->sync_map_update)
 		mail_index_sync_map_deinit(&ctx->sync_map_ctx);
 	mail_index_view_sync_clean_log_syncs(ctx);
@@ -539,7 +541,7 @@
 	}
 
 	if (view->sync_new_map != NULL) {
-		mail_index_unmap(view->index, view->map);
+		mail_index_unmap(view->index, &view->map);
 		view->map = view->sync_new_map;
 		view->sync_new_map = NULL;
 	}
--- a/src/lib-index/mail-index-view.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index-view.c	Sat Jan 14 20:47:20 2006 +0200
@@ -34,11 +34,11 @@
 	i_assert(view->refcount == 0);
 
 	mail_index_view_unlock(view);
-	mail_transaction_log_view_close(view->log_view);
+	mail_transaction_log_view_close(&view->log_view);
 
 	if (array_is_created(&view->log_syncs))
 		array_free(&view->log_syncs);
-	mail_index_unmap(view->index, view->map);
+	mail_index_unmap(view->index, &view->map);
 	if (array_is_created(&view->map_refs)) {
 		mail_index_view_unref_maps(view);
 		array_free(&view->map_refs);
@@ -153,15 +153,15 @@
 
 void mail_index_view_unref_maps(struct mail_index_view *view)
 {
-	struct mail_index_map *const *maps;
+	struct mail_index_map **maps;
 	unsigned int i, count;
 
 	if (!array_is_created(&view->map_refs))
 		return;
 
-	maps = array_get(&view->map_refs, &count);
+	maps = array_get_modifyable(&view->map_refs, &count);
 	for (i = 0; i < count; i++)
-		mail_index_unmap(view->index, maps[i]);
+		mail_index_unmap(view->index, &maps[i]);
 
 	array_clear(&view->map_refs);
 }
@@ -439,8 +439,11 @@
 	return 0;
 }
 
-void mail_index_view_close(struct mail_index_view *view)
+void mail_index_view_close(struct mail_index_view **_view)
 {
+	struct mail_index_view *view = *_view;
+
+	*_view = NULL;
 	if (--view->refcount > 0)
 		return;
 
--- a/src/lib-index/mail-index.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index.c	Sat Jan 14 20:47:20 2006 +0200
@@ -50,8 +50,11 @@
 	return index;
 }
 
-void mail_index_free(struct mail_index *index)
+void mail_index_free(struct mail_index **_index)
 {
+	struct mail_index *index = *_index;
+
+	*_index = NULL;
 	mail_index_close(index);
 
 	hash_destroy(index->keywords_hash);
@@ -569,8 +572,11 @@
 	}
 }
 
-void mail_index_unmap(struct mail_index *index, struct mail_index_map *map)
+void mail_index_unmap(struct mail_index *index, struct mail_index_map **_map)
 {
+	struct mail_index_map *map = *_map;
+
+	*_map = NULL;
 	if (--map->refcount > 0)
 		return;
 
@@ -819,7 +825,7 @@
 					  max_seq, max_offset,
 					  MAIL_TRANSACTION_TYPE_MASK) <= 0) {
 		/* can't use it. sync by re-reading index. */
-		mail_transaction_log_view_close(log_view);
+		mail_transaction_log_view_close(&log_view);
 		return 0;
 	}
 
@@ -847,8 +853,8 @@
 		index->map->hdr.log_file_ext_offset = prev_offset;
 
 	mail_index_sync_map_deinit(&sync_map_ctx);
-	mail_index_view_close(view);
-	mail_transaction_log_view_close(log_view);
+	mail_index_view_close(&view);
+	mail_transaction_log_view_close(&log_view);
 
 	*map = index->map;
 	index->map = NULL;
@@ -1031,7 +1037,7 @@
 
 	if (ret <= 0) {
 		mail_index_map_clear(index, map);
-		mail_index_unmap(index, map);
+		mail_index_unmap(index, &map);
 		index->mapping = FALSE;
 		return ret;
 	}
@@ -1508,20 +1514,12 @@
 
 void mail_index_close(struct mail_index *index)
 {
-	if (index->log != NULL) {
-		mail_transaction_log_close(index->log);
-		index->log = NULL;
-	}
-
-	if (index->map != NULL) {
-		mail_index_unmap(index, index->map);
-		index->map = NULL;
-	}
-
-	if (index->cache != NULL) {
-		mail_cache_free(index->cache);
-		index->cache = NULL;
-	}
+	if (index->log != NULL)
+		mail_transaction_log_close(&index->log);
+	if (index->map != NULL)
+		mail_index_unmap(index, &index->map);
+	if (index->cache != NULL)
+		mail_cache_free(&index->cache);
 
 	if (index->fd != -1) {
 		if (close(index->fd) < 0)
@@ -1529,10 +1527,8 @@
 		index->fd = -1;
 	}
 
-	i_free(index->copy_lock_path);
-	index->copy_lock_path = NULL;
-	i_free(index->filepath);
-	index->filepath = NULL;
+	i_free_and_null(index->copy_lock_path);
+	i_free_and_null(index->filepath);
 
 	index->indexid = 0;
 	index->opened = FALSE;
@@ -1587,12 +1583,12 @@
 		mail_index_unlock(index, lock_id);
 
 	if (ret == 0) {
-		mail_index_unmap(index, old_map);
+		mail_index_unmap(index, &old_map);
 		if (close(old_fd) < 0)
 			mail_index_set_syscall_error(index, "close()");
 	} else {
 		if (index->map != NULL)
-			mail_index_unmap(index, index->map);
+			mail_index_unmap(index, &index->map);
 		if (index->fd != -1) {
 			if (close(index->fd) < 0)
 				mail_index_set_syscall_error(index, "close()");
--- a/src/lib-index/mail-index.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-index.h	Sat Jan 14 20:47:20 2006 +0200
@@ -150,7 +150,7 @@
 struct mail_index_view_sync_ctx;
 
 struct mail_index *mail_index_alloc(const char *dir, const char *prefix);
-void mail_index_free(struct mail_index *index);
+void mail_index_free(struct mail_index **index);
 
 void mail_index_set_permissions(struct mail_index *index,
 				mode_t mode, gid_t gid);
@@ -170,7 +170,7 @@
    only when you synchronize it. The view acquires required locks
    automatically, but you'll have to drop them manually. */
 struct mail_index_view *mail_index_view_open(struct mail_index *index);
-void mail_index_view_close(struct mail_index_view *view);
+void mail_index_view_close(struct mail_index_view **view);
 
 /* Returns the index for given view. */
 struct mail_index *mail_index_view_get_index(struct mail_index_view *view);
@@ -193,10 +193,10 @@
 struct mail_index_transaction *
 mail_index_transaction_begin(struct mail_index_view *view,
 			     bool hide, bool external);
-int mail_index_transaction_commit(struct mail_index_transaction *t,
+int mail_index_transaction_commit(struct mail_index_transaction **t,
 				  uint32_t *log_file_seq_r,
 				  uoff_t *log_file_offset_r);
-void mail_index_transaction_rollback(struct mail_index_transaction *t);
+void mail_index_transaction_rollback(struct mail_index_transaction **t);
 
 /* Returns a view to transaction. Currently this differs from normal view only
    in that it contains newly appended messages in transaction. The view can
@@ -241,10 +241,10 @@
    go through all the sync records again with mail_index_sync_next(). */
 void mail_index_sync_reset(struct mail_index_sync_ctx *ctx);
 /* Commit synchronization by writing all changes to mail index file. */
-int mail_index_sync_commit(struct mail_index_sync_ctx *ctx);
+int mail_index_sync_commit(struct mail_index_sync_ctx **ctx);
 /* Rollback synchronization - none of the changes listed by sync_next() are
    actually written to index file. */
-void mail_index_sync_rollback(struct mail_index_sync_ctx *ctx);
+void mail_index_sync_rollback(struct mail_index_sync_ctx **ctx);
 
 /* Mark index file corrupted. Invalidates all views. */
 void mail_index_mark_corrupted(struct mail_index *index);
@@ -265,7 +265,7 @@
 const uint32_t *
 mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
 				 unsigned int *count_r);
-void mail_index_view_sync_end(struct mail_index_view_sync_ctx *ctx);
+void mail_index_view_sync_end(struct mail_index_view_sync_ctx **ctx);
 
 /* Returns the index header. */
 const struct mail_index_header *
@@ -333,7 +333,7 @@
 mail_index_keywords_create_from_indexes(struct mail_index_transaction *t,
 					const array_t *keyword_indexes);
 /* Free the keywords. */
-void mail_index_keywords_free(struct mail_keywords *keywords);
+void mail_index_keywords_free(struct mail_keywords **keywords);
 /* Update keywords for given message. */
 void mail_index_update_keywords(struct mail_index_transaction *t, uint32_t seq,
 				enum modify_type modify_type,
--- a/src/lib-index/mail-transaction-log-view.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-transaction-log-view.c	Sat Jan 14 20:47:20 2006 +0200
@@ -42,11 +42,14 @@
 	return view;
 }
 
-void mail_transaction_log_view_close(struct mail_transaction_log_view *view)
+void mail_transaction_log_view_close(struct mail_transaction_log_view **_view)
 {
+        struct mail_transaction_log_view *view = *_view;
 	struct mail_transaction_log_view **p;
 	struct mail_transaction_log_file *file;
 
+	*_view = NULL;
+
 	for (p = &view->log->views; *p != NULL; p = &(*p)->next) {
 		if (*p == view) {
 			*p = view->next;
--- a/src/lib-index/mail-transaction-log.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-transaction-log.c	Sat Jan 14 20:47:20 2006 +0200
@@ -242,7 +242,7 @@
 	if (log->head == NULL) {
 		/* fallback to in-memory indexes */
 		if (mail_index_move_to_memory(index) < 0) {
-			mail_transaction_log_close(log);
+			mail_transaction_log_close(&log);
 			return NULL;
 		}
 		log->head = mail_transaction_log_file_open_or_create(log, path);
@@ -255,15 +255,17 @@
 		   shouldn't happen except in race conditions.
 		   lock them and check again */
 		if (mail_transaction_log_check_file_seq(log) < 0) {
-			mail_transaction_log_close(log);
+			mail_transaction_log_close(&log);
 			return NULL;
 		}
 	}
 	return log;
 }
 
-void mail_transaction_log_close(struct mail_transaction_log *log)
+void mail_transaction_log_close(struct mail_transaction_log **_log)
 {
+	struct mail_transaction_log *log = *_log;
+
 	mail_transaction_log_views_close(log);
 
 	if (log->head != NULL) {
@@ -271,6 +273,7 @@
 		mail_transaction_logs_clean(log);
 	}
 
+	*_log = NULL;
 	log->index->log = NULL;
 	i_free(log);
 }
--- a/src/lib-index/mail-transaction-log.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-index/mail-transaction-log.h	Sat Jan 14 20:47:20 2006 +0200
@@ -107,13 +107,13 @@
 
 struct mail_transaction_log *
 mail_transaction_log_open_or_create(struct mail_index *index);
-void mail_transaction_log_close(struct mail_transaction_log *log);
+void mail_transaction_log_close(struct mail_transaction_log **log);
 
 int mail_transaction_log_move_to_memory(struct mail_transaction_log *log);
 
 struct mail_transaction_log_view *
 mail_transaction_log_view_open(struct mail_transaction_log *log);
-void mail_transaction_log_view_close(struct mail_transaction_log_view *view);
+void mail_transaction_log_view_close(struct mail_transaction_log_view **view);
 
 /* Set view boundaries. Returns -1 if error, 0 if files are lost, 1 if ok. */
 int
--- a/src/lib-mail/istream-header-filter.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-mail/istream-header-filter.c	Sat Jan 14 20:47:20 2006 +0200
@@ -45,8 +45,8 @@
 		(struct header_filter_istream *)stream;
 
 	if (mstream->hdr_ctx != NULL)
-		message_parse_header_deinit(mstream->hdr_ctx);
-	i_stream_unref(mstream->input);
+		message_parse_header_deinit(&mstream->hdr_ctx);
+	i_stream_unref(&mstream->input);
 	pool_unref(mstream->pool);
 }
 
@@ -166,7 +166,7 @@
 
 	if (hdr == NULL) {
 		/* finished */
-		message_parse_header_deinit(mstream->hdr_ctx);
+		message_parse_header_deinit(&mstream->hdr_ctx);
 		mstream->hdr_ctx = NULL;
 
 		if (!mstream->header_parsed && mstream->callback != NULL)
@@ -255,7 +255,7 @@
 	stream->buffer = NULL;
 
 	if (mstream->hdr_ctx != NULL) {
-		message_parse_header_deinit(mstream->hdr_ctx);
+		message_parse_header_deinit(&mstream->hdr_ctx);
 		mstream->hdr_ctx = NULL;
 	}
 
--- a/src/lib-mail/message-body-search.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-mail/message-body-search.c	Sat Jan 14 20:47:20 2006 +0200
@@ -155,7 +155,7 @@
 		}
 	}
 	i_assert(ret != 0);
-	message_parse_header_deinit(hdr_ctx);
+	message_parse_header_deinit(&hdr_ctx);
 
 	return found;
 }
@@ -346,10 +346,10 @@
 		pos -= data_size;
 	}
 
-	i_stream_unref(input);
+	i_stream_unref(&input);
 
 	if (ctx->translation != NULL)
-		charset_to_utf8_end(ctx->translation);
+		charset_to_utf8_end(&ctx->translation);
 	buffer_free(ctx->decode_buf);
 	return found;
 }
--- a/src/lib-mail/message-header-search.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-mail/message-header-search.c	Sat Jan 14 20:47:20 2006 +0200
@@ -71,8 +71,9 @@
 	return ctx;
 }
 
-void message_header_search_free(struct header_search_context *ctx)
+void message_header_search_free(struct header_search_context **_ctx)
 {
+        struct header_search_context *ctx = *_ctx;
 	pool_t pool;
 
 	buffer_free(ctx->match_buf);
@@ -81,6 +82,8 @@
 	p_free(pool, ctx->key);
 	p_free(pool, ctx->key_charset);
 	p_free(pool, ctx);
+
+	*_ctx = NULL;
 }
 
 static void search_with_charset(const unsigned char *data, size_t size,
--- a/src/lib-mail/message-header-search.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-mail/message-header-search.h	Sat Jan 14 20:47:20 2006 +0200
@@ -10,7 +10,7 @@
 			   bool *unknown_charset);
 
 /* Free search context. Not needed if you just destroy the pool. */
-void message_header_search_free(struct header_search_context *ctx);
+void message_header_search_free(struct header_search_context **ctx);
 
 /* Returns TRUE if key is found from header. This function may be called
    multiple times with partial header blocks, but the blocks must contain only
--- a/src/lib-mail/message-parser.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-mail/message-parser.c	Sat Jan 14 20:47:20 2006 +0200
@@ -253,7 +253,7 @@
 		parser_ctx->callback(part, NULL, parser_ctx->context);
 	if (hdr_ctx->has_nuls)
 		part->flags |= MESSAGE_PART_FLAG_HAS_NULS;
-	message_parse_header_deinit(hdr_ctx);
+	message_parse_header_deinit(&hdr_ctx);
 
 	i_assert((part->flags & MUTEX_FLAGS) != MUTEX_FLAGS);
 }
@@ -587,10 +587,12 @@
 	return ctx;
 }
 
-struct message_part *message_parser_deinit(struct message_parser_ctx *ctx)
+struct message_part *message_parser_deinit(struct message_parser_ctx **_ctx)
 {
+        struct message_parser_ctx *ctx = *_ctx;
 	struct message_part *parts = ctx->parts;
 
+	*_ctx = NULL;
 	pool_unref(ctx->parser_pool);
 	return parts;
 }
@@ -658,7 +660,7 @@
 	while ((ret = message_parse_header_next(hdr_ctx, &hdr)) > 0)
 		callback(part, hdr, context);
 	i_assert(ret != 0);
-	message_parse_header_deinit(hdr_ctx);
+	message_parse_header_deinit(&hdr_ctx);
 
 	/* call after the final skipping */
 	callback(part, NULL, context);
@@ -681,13 +683,17 @@
 	return ctx;
 }
 
-void message_parse_header_deinit(struct message_header_parser_ctx *ctx)
+void message_parse_header_deinit(struct message_header_parser_ctx **_ctx)
 {
+	struct message_header_parser_ctx *ctx = *_ctx;
+
 	i_stream_skip(ctx->input, ctx->skip);
 	if (ctx->value_buf != NULL)
 		buffer_free(ctx->value_buf);
-	str_free(ctx->name);
+	str_free(&ctx->name);
 	i_free(ctx);
+
+	*_ctx = NULL;
 }
 
 int message_parse_header_next(struct message_header_parser_ctx *ctx,
--- a/src/lib-mail/message-parser.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-mail/message-parser.h	Sat Jan 14 20:47:20 2006 +0200
@@ -84,7 +84,7 @@
    are allocated from. */
 struct message_parser_ctx *
 message_parser_init(pool_t part_pool, struct istream *input);
-struct message_part *message_parser_deinit(struct message_parser_ctx *ctx);
+struct message_part *message_parser_deinit(struct message_parser_ctx **ctx);
 
 /* Read and parse header. */
 void message_parser_parse_header(struct message_parser_ctx *ctx,
@@ -106,7 +106,7 @@
 struct message_header_parser_ctx *
 message_parse_header_init(struct istream *input, struct message_size *hdr_size,
 			 bool skip_initial_lwsp);
-void message_parse_header_deinit(struct message_header_parser_ctx *ctx);
+void message_parse_header_deinit(struct message_header_parser_ctx **ctx);
 
 /* Read and return next header line. Returns 1 if header is returned, 0 if
    input stream is non-blocking and more data needs to be read, -1 when all is
--- a/src/lib-settings/settings.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-settings/settings.c	Sat Jan 14 20:47:20 2006 +0200
@@ -223,7 +223,7 @@
 		}
 	}
 
-	i_stream_unref(input);
+	i_stream_unref(&input);
 	t_pop();
 
 	return errormsg == NULL;
--- a/src/lib-sql/driver-mysql.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-sql/driver-mysql.c	Sat Jan 14 20:47:20 2006 +0200
@@ -510,7 +510,7 @@
 {
 	const char *error;
 
-	if (sql_transaction_commit_s(ctx, &error) < 0)
+	if (sql_transaction_commit_s(&ctx, &error) < 0)
 		callback(error, context);
 	else
 		callback(NULL, context);
@@ -537,7 +537,7 @@
 		}
 		sql_result_free(result);
 	}
-	sql_transaction_rollback(_ctx);
+	sql_transaction_rollback(&_ctx);
 	return ret;
 }
 
@@ -547,7 +547,7 @@
 	struct mysql_transaction_context *ctx =
 		(struct mysql_transaction_context *)_ctx;
 
-	str_free(ctx->queries);
+	str_free(&ctx->queries);
 	i_free(ctx);
 }
 
--- a/src/lib-sql/driver-pgsql.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-sql/driver-pgsql.c	Sat Jan 14 20:47:20 2006 +0200
@@ -72,10 +72,8 @@
 
 static void driver_pgsql_close(struct pgsql_db *db)
 {
-	if (db->io != NULL) {
-		io_remove(db->io);
-		db->io = NULL;
-	}
+	if (db->io != NULL)
+		io_remove(&db->io);
 	db->io_dir = 0;
 
 	PQfinish(db->pg);
@@ -131,7 +129,7 @@
 
 	if (db->io_dir != io_dir) {
 		if (db->io != NULL)
-			io_remove(db->io);
+			io_remove(&db->io);
 		db->io = io_dir == 0 ? NULL :
 			io_add(PQsocket(db->pg), io_dir, connect_callback, db);
 		db->io_dir = io_dir;
@@ -211,8 +209,7 @@
 
 	} while (PQgetResult(db->pg) != NULL);
 
-	io_remove(db->io);
-	db->io = NULL;
+	io_remove(&db->io);
 
 	db->querying = FALSE;
 	if (db->queue != NULL && db->connected)
@@ -283,10 +280,8 @@
 		return;
 	}
 
-	if (db->io != NULL) {
-		io_remove(db->io);
-		db->io = NULL;
-	}
+	if (db->io != NULL)
+		io_remove(&db->io);
 
 	result->pgres = PQgetResult(db->pg);
 	result_finish(result);
@@ -302,8 +297,7 @@
 	if (ret > 0)
 		return;
 
-	io_remove(db->io);
-        db->io = NULL;
+	io_remove(&db->io);
 
 	if (ret < 0) {
 		db->connected = FALSE;
@@ -375,10 +369,8 @@
 	if (db->queue != NULL)
 		queue_send_next(db);
 
-	if (db->queue == NULL) {
-		timeout_remove(db->queue_to);
-                db->queue_to = NULL;
-	}
+	if (db->queue == NULL)
+		timeout_remove(&db->queue_to);
 }
 
 static void
@@ -477,7 +469,7 @@
 	else {
 		/* have to move our existing I/O handler to new I/O loop */
 		old_io = *db->io;
-		io_remove(db->io);
+		io_remove(&db->io);
 
 		db->ioloop = io_loop_create(default_pool);
 
@@ -488,8 +480,7 @@
 	driver_pgsql_query(_db, query, pgsql_query_s_callback, db);
 
 	io_loop_run(db->ioloop);
-	io_loop_destroy(db->ioloop);
-	db->ioloop = NULL;
+	io_loop_destroy(&db->ioloop);
 
 	i_assert(db->io == NULL);
 
--- a/src/lib-sql/sql-api.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-sql/sql-api.c	Sat Jan 14 20:47:20 2006 +0200
@@ -26,9 +26,10 @@
 	i_fatal("Unknown database driver '%s'", db_driver);
 }
 
-void sql_deinit(struct sql_db *db)
+void sql_deinit(struct sql_db **db)
 {
-	db->deinit(db);
+	(*db)->deinit(*db);
+	*db = NULL;
 }
 
 enum sql_db_flags sql_get_flags(struct sql_db *db)
@@ -127,20 +128,29 @@
 	return db->transaction_begin(db);
 }
 
-void sql_transaction_commit(struct sql_transaction_context *ctx,
+void sql_transaction_commit(struct sql_transaction_context **_ctx,
 			    sql_commit_callback_t *callback, void *context)
 {
+	struct sql_transaction_context *ctx = *_ctx;
+
+	*_ctx = NULL;
 	ctx->db->transaction_commit(ctx, callback, context);
 }
 
-int sql_transaction_commit_s(struct sql_transaction_context *ctx,
+int sql_transaction_commit_s(struct sql_transaction_context **_ctx,
 			     const char **error_r)
 {
+	struct sql_transaction_context *ctx = *_ctx;
+
+	*_ctx = NULL;
 	return ctx->db->transaction_commit_s(ctx, error_r);
 }
 
-void sql_transaction_rollback(struct sql_transaction_context *ctx)
+void sql_transaction_rollback(struct sql_transaction_context **_ctx)
 {
+	struct sql_transaction_context *ctx = *_ctx;
+
+	*_ctx = NULL;
 	ctx->db->transaction_rollback(ctx);
 }
 
--- a/src/lib-sql/sql-api.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-sql/sql-api.h	Sat Jan 14 20:47:20 2006 +0200
@@ -20,7 +20,7 @@
 /* Initialize database connections. db_driver is the database driver name,
    eg. "mysql" or "pgsql". connect_string is driver-specific. */
 struct sql_db *sql_init(const char *db_driver, const char *connect_string);
-void sql_deinit(struct sql_db *db);
+void sql_deinit(struct sql_db **db);
 
 /* Returns SQL database state flags. */
 enum sql_db_flags sql_get_flags(struct sql_db *db);
@@ -68,12 +68,12 @@
    transaction at a time. */
 struct sql_transaction_context *sql_transaction_begin(struct sql_db *db);
 /* Commit transaction. */
-void sql_transaction_commit(struct sql_transaction_context *ctx,
+void sql_transaction_commit(struct sql_transaction_context **ctx,
 			    sql_commit_callback_t *callback, void *context);
 /* Synchronous commit. Returns 0 if ok, -1 if error. */
-int sql_transaction_commit_s(struct sql_transaction_context *ctx,
+int sql_transaction_commit_s(struct sql_transaction_context **ctx,
 			     const char **error_r);
-void sql_transaction_rollback(struct sql_transaction_context *ctx);
+void sql_transaction_rollback(struct sql_transaction_context **ctx);
 
 /* Execute query in given transaction. */
 void sql_update(struct sql_transaction_context *ctx, const char *query);
--- a/src/lib-storage/index/dbox/dbox-file.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/dbox/dbox-file.c	Sat Jan 14 20:47:20 2006 +0200
@@ -39,7 +39,7 @@
 void dbox_file_close(struct dbox_file *file)
 {
 	if (file->input != NULL)
-		i_stream_unref(file->input);
+		i_stream_unref(&file->input);
 	if (file->fd != -1) {
 		if (close(file->fd) < 0)
 			i_error("close(dbox) failed: %m");
--- a/src/lib-storage/index/dbox/dbox-list.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/dbox/dbox-list.c	Sat Jan 14 20:47:20 2006 +0200
@@ -195,7 +195,7 @@
 	if (ctx->list_pool != NULL)
 		pool_unref(ctx->list_pool);
 	if (ctx->glob != NULL)
-		imap_match_deinit(ctx->glob);
+		imap_match_deinit(&ctx->glob);
 	i_free(ctx);
 
 	return ret;
--- a/src/lib-storage/index/dbox/dbox-save.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/dbox/dbox-save.c	Sat Jan 14 20:47:20 2006 +0200
@@ -242,7 +242,7 @@
 	}
 
 	if (dbox_uidlist_append_commit(ctx->append_ctx) < 0) {
-		mail_index_sync_rollback(ctx->index_sync_ctx);
+		mail_index_sync_rollback(&ctx->index_sync_ctx);
 		i_free(ctx);
 		return -1;
 	}
@@ -251,14 +251,14 @@
 
 void dbox_transaction_save_commit_post(struct dbox_save_context *ctx)
 {
-	mail_index_sync_rollback(ctx->index_sync_ctx);
+	mail_index_sync_rollback(&ctx->index_sync_ctx);
 	i_free(ctx);
 }
 
 void dbox_transaction_save_rollback(struct dbox_save_context *ctx)
 {
 	if (ctx->index_sync_ctx != NULL)
-		mail_index_sync_rollback(ctx->index_sync_ctx);
+		mail_index_sync_rollback(&ctx->index_sync_ctx);
 
         dbox_uidlist_append_rollback(ctx->append_ctx);
 	i_free(ctx);
--- a/src/lib-storage/index/dbox/dbox-sync-expunge.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/dbox/dbox-sync-expunge.c	Sat Jan 14 20:47:20 2006 +0200
@@ -155,7 +155,7 @@
 					      mbox->file->mail_header_size +
 					      mbox->file->seeked_mail_size);
 		ret = o_stream_send_istream(output, input);
-		i_stream_unref(input);
+		i_stream_unref(&input);
 
 		if (ret < 0) {
 			mail_storage_set_critical(STORAGE(mbox->storage),
@@ -186,7 +186,7 @@
 				break;
 		}
 	}
-	o_stream_unref(output);
+	o_stream_unref(&output);
 
 	if (ret < 0) {
 		file_dotlock_delete(&dotlock);
--- a/src/lib-storage/index/dbox/dbox-sync.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/dbox/dbox-sync.c	Sat Jan 14 20:47:20 2006 +0200
@@ -307,7 +307,7 @@
 	}
 	if (dbox_uidlist_sync_init(mbox->uidlist, &ctx.uidlist_sync_ctx,
 				   &mtime) < 0) {
-		mail_index_sync_rollback(ctx.index_sync_ctx);
+		mail_index_sync_rollback(&ctx.index_sync_ctx);
 		return -1;
 	}
 
@@ -325,7 +325,7 @@
 		ret = dbox_sync_index(&ctx);
 
 	if (ret < 0) {
-		mail_index_sync_rollback(ctx.index_sync_ctx);
+		mail_index_sync_rollback(&ctx.index_sync_ctx);
 		dbox_uidlist_sync_rollback(ctx.uidlist_sync_ctx);
 		return -1;
 	}
@@ -346,7 +346,7 @@
 	}
 
 	if (dbox_uidlist_sync_commit(ctx.uidlist_sync_ctx, &mtime) < 0) {
-		mail_index_sync_rollback(ctx.index_sync_ctx);
+		mail_index_sync_rollback(&ctx.index_sync_ctx);
 		return -1;
 	}
 
@@ -358,18 +358,18 @@
 			&sync_stamp, sizeof(sync_stamp), TRUE);
 	}
 
-	if (mail_index_transaction_commit(ctx.trans, &seq, &offset) < 0) {
+	if (mail_index_transaction_commit(&ctx.trans, &seq, &offset) < 0) {
 		mail_storage_set_index_error(&mbox->ibox);
-		mail_index_sync_rollback(ctx.index_sync_ctx);
+		mail_index_sync_rollback(&ctx.index_sync_ctx);
 		return -1;
 	}
 
 	if (force) {
-		mail_index_sync_rollback(ctx.index_sync_ctx);
+		mail_index_sync_rollback(&ctx.index_sync_ctx);
 		/* now that indexes are ok, sync changes from the index */
 		return dbox_sync(mbox, FALSE);
 	} else {
-		if (mail_index_sync_commit(ctx.index_sync_ctx) < 0) {
+		if (mail_index_sync_commit(&ctx.index_sync_ctx) < 0) {
 			mail_storage_set_index_error(&mbox->ibox);
 			return -1;
 		}
--- a/src/lib-storage/index/dbox/dbox-uidlist.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/dbox/dbox-uidlist.c	Sat Jan 14 20:47:20 2006 +0200
@@ -397,7 +397,7 @@
 		uidlist->fd = -1;
 	}
 
-	i_stream_unref(input);
+	i_stream_unref(&input);
 	return ret;
 }
 
@@ -521,7 +521,7 @@
 			"write(%s) failed: %m", uidlist->path);
 		ret = -1;
 	}
-	o_stream_unref(output);
+	o_stream_unref(&output);
 
 	if (ret < 0)
 		return -1;
@@ -664,7 +664,7 @@
 			"write(%s) failed: %m", ctx->uidlist->path);
 		ret = -1;
 	}
-	o_stream_unref(output);
+	o_stream_unref(&output);
 
 	if (ret < 0)
 		return -1;
@@ -933,7 +933,7 @@
 	save_file->file = file = p_new(ctx->pool, struct dbox_file, 1);
         save_file->dotlock = dotlock;
 	file->file_seq = file_seq;
-	file->path = str_free_without_data(str);
+	file->path = str_free_without_data(&str);
 
 	file->fd = open(file->path, O_CREAT | O_RDWR, 0600);
 	if (file->fd == -1) {
@@ -955,7 +955,7 @@
 	/* we'll be using CRLF linefeeds always */
 	output = o_stream_create_file(file->fd, default_pool, 0, FALSE);
 	file->output = o_stream_create_crlf(default_pool, output);
-	o_stream_unref(output);
+	o_stream_unref(&output);
 
 	if ((uoff_t)st.st_size < sizeof(struct dbox_file_header)) {
 		if (dbox_file_write_header(mbox, file) < 0) {
--- a/src/lib-storage/index/index-mail-headers.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/index-mail-headers.c	Sat Jan 14 20:47:20 2006 +0200
@@ -406,7 +406,7 @@
 				     imap_envelope_parse_callback, mail);
 		mail->data.save_envelope = FALSE;
 	}
-	mailbox_header_lookup_deinit(header_ctx);
+	mailbox_header_lookup_deinit(&header_ctx);
 }
 
 static size_t get_header_size(buffer_t *buffer, size_t pos)
@@ -539,7 +539,7 @@
 		headers_ctx = mailbox_header_lookup_init(&mail->ibox->box,
 							 headers);
 		ret = index_mail_parse_headers(mail, headers_ctx);
-		mailbox_header_lookup_deinit(headers_ctx);
+		mailbox_header_lookup_deinit(&headers_ctx);
 		if (ret < 0)
 			return NULL;
 
@@ -624,7 +624,7 @@
 		return NULL;
 
 	if (mail->data.filter_stream != NULL)
-		i_stream_unref(mail->data.filter_stream);
+		i_stream_unref(&mail->data.filter_stream);
 
 	index_mail_parse_header_init(mail, _headers);
 	mail->data.filter_stream =
--- a/src/lib-storage/index/index-mail.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/index-mail.c	Sat Jan 14 20:47:20 2006 +0200
@@ -371,7 +371,7 @@
 	} else {
 		message_parser_parse_body(data->parser_ctx, NULL, NULL, NULL);
 	}
-	data->parts = message_parser_deinit(data->parser_ctx);
+	data->parts = message_parser_deinit(&data->parser_ctx);
         data->parser_ctx = NULL;
 
 	if (data->parsed_bodystructure &&
@@ -734,9 +734,9 @@
 static void index_mail_close(struct index_mail *mail)
 {
 	if (mail->data.stream != NULL)
-		i_stream_unref(mail->data.stream);
+		i_stream_unref(&mail->data.stream);
 	if (mail->data.filter_stream != NULL)
-		i_stream_unref(mail->data.filter_stream);
+		i_stream_unref(&mail->data.filter_stream);
 }
 
 int index_mail_set_seq(struct mail *_mail, uint32_t seq)
--- a/src/lib-storage/index/index-mailbox-check.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/index-mailbox-check.c	Sat Jan 14 20:47:20 2006 +0200
@@ -118,12 +118,10 @@
 		aio = ibox->notify_ios;
 		ibox->notify_ios = aio->next;
 
-		io_remove(aio->io);
+		io_remove(&aio->io);
 		i_free(aio);
 	}
 
-	if (ibox->notify_to != NULL) {
-		timeout_remove(ibox->notify_to);
-		ibox->notify_to = NULL;
-	}
+	if (ibox->notify_to != NULL)
+		timeout_remove(&ibox->notify_to);
 }
--- a/src/lib-storage/index/index-search.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/index-search.c	Sat Jan 14 20:47:20 2006 +0200
@@ -515,7 +515,7 @@
 							   headers);
 			input = mail_get_header_stream(ctx->mail, headers_ctx);
 			if (input == NULL) {
-				mailbox_header_lookup_deinit(headers_ctx);
+				mailbox_header_lookup_deinit(&headers_ctx);
 				return FALSE;
 			}
 		}
@@ -530,7 +530,7 @@
 		message_parse_header(NULL, input, NULL,
 				     search_header, &hdr_ctx);
 		if (headers_ctx != NULL)
-			mailbox_header_lookup_deinit(headers_ctx);
+			mailbox_header_lookup_deinit(&headers_ctx);
 	} else {
 		struct message_size hdr_size;
 
--- a/src/lib-storage/index/index-storage.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/index-storage.c	Sat Jan 14 20:47:20 2006 +0200
@@ -81,7 +81,7 @@
 
 static void index_list_free(struct index_list *list)
 {
-	mail_index_free(list->index);
+	mail_index_free(&list->index);
 	i_free(list->mailbox_path);
 	i_free(list);
 }
@@ -165,10 +165,8 @@
 		}
 	}
 
-	if (indexes == NULL && to_index != NULL) {
-		timeout_remove(to_index);
-		to_index = NULL;
-	}
+	if (indexes == NULL && to_index != NULL)
+		timeout_remove(&to_index);
 }
 
 static void index_removal_timeout(void *context __attr_unused__)
@@ -374,7 +372,7 @@
 	struct index_mailbox *ibox = (struct index_mailbox *) box;
 
 	if (ibox->view != NULL)
-		mail_index_view_close(ibox->view);
+		mail_index_view_close(&ibox->view);
 
 	index_mailbox_check_remove_all(ibox);
 	if (ibox->index != NULL)
@@ -454,5 +452,5 @@
 void index_keywords_free(struct mailbox_transaction_context *t __attr_unused__,
 			 struct mail_keywords *keywords)
 {
-	mail_index_keywords_free(keywords);
+	mail_index_keywords_free(&keywords);
 }
--- a/src/lib-storage/index/index-sync.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/index-sync.c	Sat Jan 14 20:47:20 2006 +0200
@@ -248,7 +248,7 @@
 	int ret = ctx->failed ? -1 : 0;
 
 	if (ctx->sync_ctx != NULL)
-		mail_index_view_sync_end(ctx->sync_ctx);
+		mail_index_view_sync_end(&ctx->sync_ctx);
 
 	if (ret == 0) {
 		messages_count = mail_index_view_get_messages_count(ibox->view);
--- a/src/lib-storage/index/index-transaction.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/index-transaction.c	Sat Jan 14 20:47:20 2006 +0200
@@ -27,7 +27,7 @@
 static void index_transaction_free(struct index_transaction_context *t)
 {
 	mail_cache_view_close(t->cache_view);
-	mail_index_view_close(t->trans_view);
+	mail_index_view_close(&t->trans_view);
 	mail_index_view_unlock(t->ibox->view);
 	array_free(&t->mailbox_ctx.module_contexts);
 	i_free(t);
@@ -41,7 +41,7 @@
 	uoff_t offset;
 	int ret;
 
-	ret = mail_index_transaction_commit(t->trans, &seq, &offset);
+	ret = mail_index_transaction_commit(&t->trans, &seq, &offset);
 	if (ret < 0)
 		mail_storage_set_index_error(t->ibox);
 	else {
@@ -60,6 +60,6 @@
 	struct index_transaction_context *t =
 		(struct index_transaction_context *)_t;
 
-	mail_index_transaction_rollback(t->trans);
+	mail_index_transaction_rollback(&t->trans);
 	index_transaction_free(t);
 }
--- a/src/lib-storage/index/maildir/maildir-keywords.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/maildir/maildir-keywords.c	Sat Jan 14 20:47:20 2006 +0200
@@ -137,7 +137,7 @@
 		strp = array_idx_modifyable(&mk->list, idx);
 		*strp = new_name;
 	}
-	i_stream_unref(input);
+	i_stream_unref(&input);
 
 	if (close(fd) < 0) {
                 mail_storage_set_critical(STORAGE(mk->mbox->storage),
--- a/src/lib-storage/index/maildir/maildir-save.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/maildir/maildir-save.c	Sat Jan 14 20:47:20 2006 +0200
@@ -159,7 +159,7 @@
 		       MAIL_STORAGE_FLAG_SAVE_CRLF) != 0 ?
 		o_stream_create_crlf(default_pool, output) :
 		o_stream_create_lf(default_pool, output);
-	o_stream_unref(output);
+	o_stream_unref(&output);
 
 	flags &= ~MAIL_RECENT;
 	if (mbox->ibox.keep_recent)
@@ -255,8 +255,7 @@
 	}
 
 	output_errno = ctx->output->stream_errno;
-	o_stream_unref(ctx->output);
-	ctx->output = NULL;
+	o_stream_unref(&ctx->output);
 
 	/* FIXME: when saving multiple messages, we could get better
 	   performance if we left the fd open and fsync()ed it later */
--- a/src/lib-storage/index/maildir/maildir-sync.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/maildir/maildir-sync.c	Sat Jan 14 20:47:20 2006 +0200
@@ -840,7 +840,7 @@
 
 void maildir_sync_index_abort(struct maildir_index_sync_context *sync_ctx)
 {
-	mail_index_sync_rollback(sync_ctx->sync_ctx);
+	mail_index_sync_rollback(&sync_ctx->sync_ctx);
 	maildir_keywords_sync_deinit(sync_ctx->keywords_sync_ctx);
 	i_free(sync_ctx);
 }
@@ -955,7 +955,7 @@
 					trans, &keywords);
 				mail_index_update_keywords(trans, seq,
 							   MODIFY_REPLACE, kw);
-				mail_index_keywords_free(kw);
+				mail_index_keywords_free(&kw);
 			}
 			continue;
 		}
@@ -1057,7 +1057,7 @@
 				trans, &keywords);
 			mail_index_update_keywords(trans, seq,
 						   MODIFY_REPLACE, kw);
-			mail_index_keywords_free(kw);
+			mail_index_keywords_free(&kw);
 		}
 	}
 	maildir_uidlist_iter_deinit(iter);
@@ -1137,19 +1137,19 @@
 	}
 
 	if (ret < 0) {
-		mail_index_transaction_rollback(trans);
-		mail_index_sync_rollback(sync_ctx->sync_ctx);
+		mail_index_transaction_rollback(&trans);
+		mail_index_sync_rollback(&sync_ctx->sync_ctx);
 	} else {
 		uint32_t seq;
 		uoff_t offset;
 
-		if (mail_index_transaction_commit(trans, &seq, &offset) < 0)
+		if (mail_index_transaction_commit(&trans, &seq, &offset) < 0)
 			ret = -1;
 		else if (seq != 0) {
 			mbox->ibox.commit_log_file_seq = seq;
 			mbox->ibox.commit_log_file_offset = offset;
 		}
-		if (mail_index_sync_commit(sync_ctx->sync_ctx) < 0)
+		if (mail_index_sync_commit(&sync_ctx->sync_ctx) < 0)
 			ret = -1;
 	}
 	maildir_keywords_sync_deinit(sync_ctx->keywords_sync_ctx);
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Sat Jan 14 20:47:20 2006 +0200
@@ -332,7 +332,7 @@
                 uidlist->last_mtime = 0;
 	}
 
-	i_stream_unref(input);
+	i_stream_unref(&input);
 	uidlist->initial_read = TRUE;
 	return ret;
 }
--- a/src/lib-storage/index/mbox/istream-raw-mbox.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/mbox/istream-raw-mbox.c	Sat Jan 14 20:47:20 2006 +0200
@@ -32,7 +32,7 @@
 	i_free(rstream->next_sender);
 
 	i_stream_seek(rstream->input, rstream->istream.istream.v_offset);
-	i_stream_unref(rstream->input);
+	i_stream_unref(&rstream->input);
 }
 
 static void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
--- a/src/lib-storage/index/mbox/mbox-file.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/mbox/mbox-file.c	Sat Jan 14 20:47:20 2006 +0200
@@ -126,10 +126,8 @@
 	/* if we read anything, fix the atime if needed */
 	mbox_file_fix_atime(mbox);
 
-	if (mbox->mbox_stream != NULL) {
-		i_stream_unref(mbox->mbox_stream);
-		mbox->mbox_stream = NULL;
-	}
+	if (mbox->mbox_stream != NULL)
+		i_stream_unref(&mbox->mbox_stream);
 
 	if (mbox->mbox_file_stream != NULL) {
 		if (mbox->mbox_fd == -1) {
@@ -137,8 +135,7 @@
 			i_assert(mbox->mbox_readonly);
 		} else {
 			i_stream_close(mbox->mbox_file_stream);
-			i_stream_unref(mbox->mbox_file_stream);
-			mbox->mbox_file_stream = NULL;
+			i_stream_unref(&mbox->mbox_file_stream);
 		}
 	}
 }
--- a/src/lib-storage/index/mbox/mbox-list.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/mbox/mbox-list.c	Sat Jan 14 20:47:20 2006 +0200
@@ -201,7 +201,7 @@
 	if (ctx->list_pool != NULL)
 		pool_unref(ctx->list_pool);
 	if (ctx->glob != NULL)
-		imap_match_deinit(ctx->glob);
+		imap_match_deinit(&ctx->glob);
 	i_free(ctx);
 
 	return ret;
--- a/src/lib-storage/index/mbox/mbox-mail.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/mbox/mbox-mail.c	Sat Jan 14 20:47:20 2006 +0200
@@ -194,7 +194,7 @@
 						      mbox_hide_headers,
 						      mbox_hide_headers_count,
 						      NULL, NULL);
-		i_stream_unref(raw_stream);
+		i_stream_unref(&raw_stream);
 	}
 
 	return index_mail_init_stream(mail, hdr_size, body_size);
--- a/src/lib-storage/index/mbox/mbox-save.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/mbox/mbox-save.c	Sat Jan 14 20:47:20 2006 +0200
@@ -201,7 +201,7 @@
 	ctx->synced = TRUE;
         t->mbox_modified = TRUE;
 
-	mail_index_view_close(view);
+	mail_index_view_close(&view);
 }
 
 static void status_flags_append(string_t *str, enum mail_flags flags,
@@ -524,14 +524,10 @@
 			ctx->failed = TRUE;
 	}
 
-	if (ctx->input != NULL) {
-		i_stream_unref(ctx->input);
-		ctx->input = NULL;
-	}
-	if (ctx->body_output != NULL) {
-		o_stream_unref(ctx->body_output);
-		ctx->body_output = NULL;
-	}
+	if (ctx->input != NULL)
+		i_stream_unref(&ctx->input);
+	if (ctx->body_output != NULL)
+		o_stream_unref(&ctx->body_output);
 
 	if (ctx->failed && ctx->mail_offset != (uoff_t)-1) {
 		/* saving this mail failed - truncate back to beginning of it */
@@ -566,10 +562,10 @@
 	i_assert(ctx->body_output == NULL);
 
 	if (ctx->output != NULL)
-		o_stream_unref(ctx->output);
+		o_stream_unref(&ctx->output);
 	if (ctx->mail != NULL)
 		index_mail_free(ctx->mail);
-	str_free(ctx->headers);
+	str_free(&ctx->headers);
 	i_free(ctx);
 }
 
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Sat Jan 14 20:47:20 2006 +0200
@@ -972,10 +972,8 @@
 	}
 
         mbox_file_close(mbox);
-	if (mbox->mbox_file_stream != NULL) {
-		i_stream_unref(mbox->mbox_file_stream);
-		mbox->mbox_file_stream = NULL;
-	}
+	if (mbox->mbox_file_stream != NULL)
+		i_stream_unref(&mbox->mbox_file_stream);
 
 	index_storage_mailbox_free(box);
 	return ret;
--- a/src/lib-storage/index/mbox/mbox-sync-parse.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/mbox/mbox-sync-parse.c	Sat Jan 14 20:47:20 2006 +0200
@@ -512,7 +512,7 @@
 			str_append_c(ctx->header, '\n');
 	}
 	i_assert(ret != 0);
-	message_parse_header_deinit(hdr_ctx);
+	message_parse_header_deinit(&hdr_ctx);
 
 	mbox_md5_finish(mbox_md5_ctx, ctx->hdr_md5_sum);
 
@@ -575,7 +575,7 @@
 		}
 	}
 	i_assert(ret != 0);
-	message_parse_header_deinit(hdr_ctx);
+	message_parse_header_deinit(&hdr_ctx);
 
 	mbox_md5_finish(mbox_md5_ctx, ctx.hdr_md5_sum);
 
--- a/src/lib-storage/index/mbox/mbox-sync-rewrite.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/mbox/mbox-sync-rewrite.c	Sat Jan 14 20:47:20 2006 +0200
@@ -34,7 +34,7 @@
 	input = i_stream_create_limit(default_pool, sync_ctx->file_input,
 				      source, size);
 	ret = o_stream_send_istream(output, input);
-	i_stream_unref(input);
+	i_stream_unref(&input);
 
         if (ret == (off_t)size)
 		ret = 0;
@@ -51,7 +51,7 @@
 	}
 
 	i_stream_sync(sync_ctx->input);
-	o_stream_unref(output);
+	o_stream_unref(&output);
 	return (int)ret;
 }
 
--- a/src/lib-storage/index/mbox/mbox-sync.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Sat Jan 14 20:47:20 2006 +0200
@@ -401,7 +401,7 @@
 						&mail_ctx->mail.keywords);
 	mail_index_update_keywords(sync_ctx->t, sync_ctx->idx_seq,
 				   MODIFY_REPLACE, keywords);
-	mail_index_keywords_free(keywords);
+	mail_index_keywords_free(&keywords);
 }
 
 static int
@@ -1457,7 +1457,7 @@
 		i_assert(sync_ctx->mbox->mbox_sync_dirty);
 		mbox_sync_restart(sync_ctx);
 
-		mail_index_transaction_rollback(sync_ctx->t);
+		mail_index_transaction_rollback(&sync_ctx->t);
 		sync_ctx->t = mail_index_transaction_begin(sync_ctx->sync_view,
 							   FALSE, TRUE);
 
@@ -1525,12 +1525,12 @@
 static void mbox_sync_context_free(struct mbox_sync_context *sync_ctx)
 {
 	if (sync_ctx->t != NULL)
-		mail_index_transaction_rollback(sync_ctx->t);
+		mail_index_transaction_rollback(&sync_ctx->t);
 	if (sync_ctx->index_sync_ctx != NULL)
-		mail_index_sync_rollback(sync_ctx->index_sync_ctx);
+		mail_index_sync_rollback(&sync_ctx->index_sync_ctx);
 	pool_unref(sync_ctx->mail_keyword_pool);
-	str_free(sync_ctx->header);
-	str_free(sync_ctx->from_line);
+	str_free(&sync_ctx->header);
+	str_free(&sync_ctx->from_line);
 	array_free(&sync_ctx->mails);
 	array_free(&sync_ctx->syncs);
 }
@@ -1625,7 +1625,7 @@
 
 		/* index may need to do internal syncing though, so commit
 		   instead of rollbacking. */
-		if (mail_index_sync_commit(index_sync_ctx) < 0) {
+		if (mail_index_sync_commit(&index_sync_ctx) < 0) {
 			mail_storage_set_index_error(&mbox->ibox);
 			return -1;
 		}
@@ -1663,7 +1663,7 @@
 		if (mbox_sync_read_index_syncs(&sync_ctx, 1, &expunged) < 0)
 			return -1;
 		if (sync_ctx.sync_rec.uid1 == 0) {
-			if (mail_index_transaction_commit(sync_ctx.t,
+			if (mail_index_transaction_commit(&sync_ctx.t,
 							  &seq, &offset) < 0) {
 				mail_storage_set_index_error(&mbox->ibox);
 				mbox_sync_context_free(&sync_ctx);
@@ -1701,8 +1701,9 @@
 	ret = mbox_sync_do(&sync_ctx, flags);
 
 	if (ret < 0)
-		mail_index_transaction_rollback(sync_ctx.t);
-	else if (mail_index_transaction_commit(sync_ctx.t, &seq, &offset) < 0) {
+		mail_index_transaction_rollback(&sync_ctx.t);
+	else if (mail_index_transaction_commit(&sync_ctx.t,
+					       &seq, &offset) < 0) {
 		mail_storage_set_index_error(&mbox->ibox);
 		ret = -1;
 	} else {
@@ -1712,8 +1713,8 @@
 	sync_ctx.t = NULL;
 
 	if (ret < 0)
-		mail_index_sync_rollback(index_sync_ctx);
-	else if (mail_index_sync_commit(index_sync_ctx) < 0) {
+		mail_index_sync_rollback(&index_sync_ctx);
+	else if (mail_index_sync_commit(&index_sync_ctx) < 0) {
 		mail_storage_set_index_error(&mbox->ibox);
 		ret = -1;
 	}
--- a/src/lib-storage/mail-copy.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/mail-copy.c	Sat Jan 14 20:47:20 2006 +0200
@@ -29,9 +29,9 @@
 	}
 
 	if (input->stream_errno != 0) {
-		mailbox_save_cancel(ctx);
+		mailbox_save_cancel(&ctx);
 		return -1;
 	}
 
-	return mailbox_save_finish(ctx, dest_mail);
+	return mailbox_save_finish(&ctx, dest_mail);
 }
--- a/src/lib-storage/mail-storage.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/mail-storage.c	Sat Jan 14 20:47:20 2006 +0200
@@ -145,10 +145,13 @@
 	return storage;
 }
 
-void mail_storage_destroy(struct mail_storage *storage)
+void mail_storage_destroy(struct mail_storage **_storage)
 {
+	struct mail_storage *storage = *_storage;
+
 	i_assert(storage != NULL);
 
+	*_storage = NULL;
 	storage->v.destroy(storage);
 }
 
@@ -265,8 +268,11 @@
 	return ctx->storage->v.mailbox_list_next(ctx);
 }
 
-int mail_storage_mailbox_list_deinit(struct mailbox_list_context *ctx)
+int mail_storage_mailbox_list_deinit(struct mailbox_list_context **_ctx)
 {
+	struct mailbox_list_context *ctx = *_ctx;
+
+	*_ctx = NULL;
 	return ctx->storage->v.mailbox_list_deinit(ctx);
 }
 
@@ -298,8 +304,11 @@
 	return storage->v.mailbox_open(storage, name, input, flags);
 }
 
-int mailbox_close(struct mailbox *box)
+int mailbox_close(struct mailbox **_box)
 {
+	struct mailbox *box = *_box;
+
+	*_box = NULL;
 	return box->v.close(box);
 }
 
@@ -342,9 +351,12 @@
 	return ctx->box->v.sync_next(ctx, sync_rec_r);
 }
 
-int mailbox_sync_deinit(struct mailbox_sync_context *ctx,
+int mailbox_sync_deinit(struct mailbox_sync_context **_ctx,
 			struct mailbox_status *status_r)
 {
+	struct mailbox_sync_context *ctx = *_ctx;
+
+	*_ctx = NULL;
 	return ctx->box->v.sync_deinit(ctx, status_r);
 }
 
@@ -362,8 +374,11 @@
 }
 
 void mailbox_keywords_free(struct mailbox_transaction_context *t,
-			   struct mail_keywords *keywords)
+			   struct mail_keywords **_keywords)
 {
+	struct mail_keywords *keywords = *_keywords;
+
+	*_keywords = NULL;
 	t->box->v.keywords_free(t, keywords);
 }
 
@@ -379,8 +394,11 @@
 	return box->v.header_lookup_init(box, headers);
 }
 
-void mailbox_header_lookup_deinit(struct mailbox_header_lookup_ctx *ctx)
+void mailbox_header_lookup_deinit(struct mailbox_header_lookup_ctx **_ctx)
 {
+	struct mailbox_header_lookup_ctx *ctx = *_ctx;
+
+	*_ctx = NULL;
 	ctx->box->v.header_lookup_deinit(ctx);
 }
 
@@ -398,8 +416,11 @@
 	return t->box->v.search_init(t, charset, args, sort_program);
 }
 
-int mailbox_search_deinit(struct mail_search_context *ctx)
+int mailbox_search_deinit(struct mail_search_context **_ctx)
 {
+	struct mail_search_context *ctx = *_ctx;
+
+	*_ctx = NULL;
 	return ctx->transaction->box->v.search_deinit(ctx);
 }
 
@@ -415,14 +436,20 @@
 	return box->v.transaction_begin(box, flags);
 }
 
-int mailbox_transaction_commit(struct mailbox_transaction_context *t,
+int mailbox_transaction_commit(struct mailbox_transaction_context **_t,
 			       enum mailbox_sync_flags flags)
 {
+	struct mailbox_transaction_context *t = *_t;
+
+	*_t = NULL;
 	return t->box->v.transaction_commit(t, flags);
 }
 
-void mailbox_transaction_rollback(struct mailbox_transaction_context *t)
+void mailbox_transaction_rollback(struct mailbox_transaction_context **_t)
 {
+	struct mailbox_transaction_context *t = *_t;
+
+	*_t = NULL;
 	t->box->v.transaction_rollback(t);
 }
 
@@ -443,13 +470,19 @@
 	return ctx->transaction->box->v.save_continue(ctx);
 }
 
-int mailbox_save_finish(struct mail_save_context *ctx, struct mail *dest_mail)
+int mailbox_save_finish(struct mail_save_context **_ctx, struct mail *dest_mail)
 {
+	struct mail_save_context *ctx = *_ctx;
+
+	*_ctx = NULL;
 	return ctx->transaction->box->v.save_finish(ctx, dest_mail);
 }
 
-void mailbox_save_cancel(struct mail_save_context *ctx)
+void mailbox_save_cancel(struct mail_save_context **_ctx)
 {
+	struct mail_save_context *ctx = *_ctx;
+
+	*_ctx = NULL;
 	ctx->transaction->box->v.save_cancel(ctx);
 }
 
--- a/src/lib-storage/mail-storage.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/mail-storage.h	Sat Jan 14 20:47:20 2006 +0200
@@ -223,7 +223,7 @@
 mail_storage_create(const char *name, const char *data, const char *user,
 		    enum mail_storage_flags flags,
 		    enum mail_storage_lock_method lock_method);
-void mail_storage_destroy(struct mail_storage *storage);
+void mail_storage_destroy(struct mail_storage **storage);
 
 struct mail_storage *
 mail_storage_create_default(const char *user, enum mail_storage_flags flags,
@@ -271,7 +271,7 @@
 mail_storage_mailbox_list_next(struct mailbox_list_context *ctx);
 /* Deinitialize mailbox list request. Returns FALSE if some error
    occurred while listing. */
-int mail_storage_mailbox_list_deinit(struct mailbox_list_context *ctx);
+int mail_storage_mailbox_list_deinit(struct mailbox_list_context **ctx);
 
 /* Subscribe/unsubscribe mailbox. There should be no error when
    subscribing to already subscribed mailbox. Subscribing to
@@ -300,7 +300,7 @@
 			     enum mailbox_open_flags flags);
 /* Close the box. Returns -1 if some cleanup errors occurred, but
    the mailbox was closed anyway. */
-int mailbox_close(struct mailbox *box);
+int mailbox_close(struct mailbox **box);
 
 /* Returns storage of given mailbox */
 struct mail_storage *mailbox_get_storage(struct mailbox *box);
@@ -323,7 +323,7 @@
 mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags);
 int mailbox_sync_next(struct mailbox_sync_context *ctx,
 		      struct mailbox_sync_rec *sync_rec_r);
-int mailbox_sync_deinit(struct mailbox_sync_context *ctx,
+int mailbox_sync_deinit(struct mailbox_sync_context **ctx,
 			struct mailbox_status *status_r);
 
 /* Call given callback function when something changes in the mailbox.
@@ -334,16 +334,16 @@
 struct mailbox_transaction_context *
 mailbox_transaction_begin(struct mailbox *box,
 			  enum mailbox_transaction_flags flags);
-int mailbox_transaction_commit(struct mailbox_transaction_context *t,
+int mailbox_transaction_commit(struct mailbox_transaction_context **t,
 			       enum mailbox_sync_flags flags);
-void mailbox_transaction_rollback(struct mailbox_transaction_context *t);
+void mailbox_transaction_rollback(struct mailbox_transaction_context **t);
 
 /* Build mail_keywords from NULL-terminated keywords list. */
 struct mail_keywords *
 mailbox_keywords_create(struct mailbox_transaction_context *t,
 			const char *const keywords[]);
 void mailbox_keywords_free(struct mailbox_transaction_context *t,
-			   struct mail_keywords *keywords);
+			   struct mail_keywords **keywords);
 
 /* Convert uid range to sequence range. */
 int mailbox_get_uids(struct mailbox *box, uint32_t uid1, uint32_t uid2,
@@ -352,7 +352,7 @@
 /* Initialize header lookup for given headers. */
 struct mailbox_header_lookup_ctx *
 mailbox_header_lookup_init(struct mailbox *box, const char *const headers[]);
-void mailbox_header_lookup_deinit(struct mailbox_header_lookup_ctx *ctx);
+void mailbox_header_lookup_deinit(struct mailbox_header_lookup_ctx **ctx);
 
 /* Modify sort_program to specify a sort program acceptable for
    search_init(). If mailbox supports no sorting, it's simply set to
@@ -370,7 +370,7 @@
 		    const char *charset, struct mail_search_arg *args,
 		    const enum mail_sort_type *sort_program);
 /* Deinitialize search request. */
-int mailbox_search_deinit(struct mail_search_context *ctx);
+int mailbox_search_deinit(struct mail_search_context **ctx);
 /* Search the next message. Returns 1 if found, 0 if not, -1 if failure. */
 int mailbox_search_next(struct mail_search_context *ctx, struct mail *mail);
 
@@ -388,8 +388,8 @@
 		  const char *from_envelope, struct istream *input,
 		  bool want_mail);
 int mailbox_save_continue(struct mail_save_context *ctx);
-int mailbox_save_finish(struct mail_save_context *ctx, struct mail *dest_mail);
-void mailbox_save_cancel(struct mail_save_context *ctx);
+int mailbox_save_finish(struct mail_save_context **ctx, struct mail *dest_mail);
+void mailbox_save_cancel(struct mail_save_context **ctx);
 
 /* Copy given message. If dest_mail is non-NULL, the copied message can be
    accessed using it. Note that setting it non-NULL may require mailbox
@@ -415,7 +415,7 @@
 struct mail *mail_alloc(struct mailbox_transaction_context *t,
 			enum mail_fetch_field wanted_fields,
 			struct mailbox_header_lookup_ctx *wanted_headers);
-void mail_free(struct mail *mail);
+void mail_free(struct mail **mail);
 int mail_set_seq(struct mail *mail, uint32_t seq);
 
 /* Get the time message was received (IMAP INTERNALDATE).
--- a/src/lib-storage/mail.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/mail.c	Sat Jan 14 20:47:20 2006 +0200
@@ -11,11 +11,12 @@
 	return t->box->v.mail_alloc(t, wanted_fields, wanted_headers);
 }
 
-void mail_free(struct mail *mail)
+void mail_free(struct mail **mail)
 {
-	struct mail_private *p = (struct mail_private *)mail;
+	struct mail_private *p = (struct mail_private *)*mail;
 
-	p->v.free(mail);
+	p->v.free(*mail);
+	*mail = NULL;
 }
 
 int mail_set_seq(struct mail *mail, uint32_t seq)
--- a/src/lib-storage/subscription-file/subscription-file.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib-storage/subscription-file/subscription-file.c	Sat Jan 14 20:47:20 2006 +0200
@@ -139,8 +139,8 @@
 	}
 
 	if (input != NULL)
-		i_stream_unref(input);
-	o_stream_unref(output);
+		i_stream_unref(&input);
+	o_stream_unref(&output);
 
 	if (failed || (set && found) || (!set && !found)) {
 		if (file_dotlock_delete(&dotlock) < 0) {
@@ -190,7 +190,7 @@
 
 	failed = ctx->failed;
 	if (ctx->input != NULL)
-		i_stream_unref(ctx->input);
+		i_stream_unref(&ctx->input);
 	pool_unref(ctx->pool);
 
 	return failed ? -1 : 0;
--- a/src/lib/buffer.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/buffer.c	Sat Jan 14 20:47:20 2006 +0200
@@ -113,20 +113,23 @@
 	return (buffer_t *)buf;
 }
 
-void buffer_free(buffer_t *_buf)
+void _buffer_free(buffer_t **_buf)
 {
-	struct real_buffer *buf = (struct real_buffer *)_buf;
+	struct real_buffer *buf = (struct real_buffer *)*_buf;
 
+	*_buf = NULL;
 	if (buf->alloced)
 		p_free(buf->pool, buf->w_buffer);
 	p_free(buf->pool, buf);
 }
 
-void *buffer_free_without_data(buffer_t *_buf)
+void *_buffer_free_without_data(buffer_t **_buf)
 {
-	struct real_buffer *buf = (struct real_buffer *)_buf;
+	struct real_buffer *buf = (struct real_buffer *)*_buf;
 	void *data;
 
+	*_buf = NULL;
+
 	data = buf->w_buffer;
 	p_free(buf->pool, buf);
 	return data;
--- a/src/lib/buffer.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/buffer.h	Sat Jan 14 20:47:20 2006 +0200
@@ -27,10 +27,12 @@
 buffer_t *buffer_create_dynamic(pool_t pool, size_t init_size);
 /* Free the memory used by buffer. Not needed if the memory is free'd
    directly from the memory pool. */
-void buffer_free(buffer_t *buf);
+void _buffer_free(buffer_t **buf);
+#define buffer_free(buf) _buffer_free(&(buf))
 /* Free the memory used by buffer structure, but return the buffer data
    unfree'd. */
-void *buffer_free_without_data(buffer_t *buf);
+void *_buffer_free_without_data(buffer_t **buf);
+#define buffer_free_without_data(buf) _buffer_free_without_data(&(buf))
 
 /* Reset the buffer. used size and it's contents are zeroed. */
 void buffer_reset(buffer_t *buf);
--- a/src/lib/file-cache.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/file-cache.c	Sat Jan 14 20:47:20 2006 +0200
@@ -26,8 +26,12 @@
 	return cache;
 }
 
-void file_cache_free(struct file_cache *cache)
+void file_cache_free(struct file_cache **_cache)
 {
+	struct file_cache *cache = *_cache;
+
+	*_cache = NULL;
+
 	if (cache->mmap_base != NULL) {
 		if (munmap_anon(cache->mmap_base, cache->mmap_length) < 0)
 			i_error("munmap_anon() failed: %m");
--- a/src/lib/file-cache.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/file-cache.h	Sat Jan 14 20:47:20 2006 +0200
@@ -4,7 +4,8 @@
 /* Create a new file cache. It works very much like file-backed mmap()ed
    memory, but it works more nicely with remote filesystems (no SIGBUS). */
 struct file_cache *file_cache_new(int fd);
-void file_cache_free(struct file_cache *cache);
+/* Destroy the cache and set cache pointer to NULL. */
+void file_cache_free(struct file_cache **cache);
 
 /* Change cached file descriptor. Invalidates the whole cache. */
 void file_cache_set_fd(struct file_cache *cache, int fd);
--- a/src/lib/hash.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/hash.c	Sat Jan 14 20:47:20 2006 +0200
@@ -103,8 +103,12 @@
 	}
 }
 
-void hash_destroy(struct hash_table *table)
+void _hash_destroy(struct hash_table **_table)
 {
+	struct hash_table *table = *_table;
+
+	*_table = NULL;
+
 	if (!table->node_pool->alloconly_pool) {
 		hash_destroy_nodes(table);
 		destroy_node_list(table, table->free_nodes);
--- a/src/lib/hash.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/hash.h	Sat Jan 14 20:47:20 2006 +0200
@@ -15,8 +15,8 @@
 struct hash_table *
 hash_create(pool_t table_pool, pool_t node_pool, size_t initial_size,
 	    hash_callback_t *hash_cb, hash_cmp_callback_t *key_compare_cb);
-void hash_destroy(struct hash_table *table);
-
+void _hash_destroy(struct hash_table **table);
+#define hash_destroy(table) _hash_destroy(&(table))
 /* Remove all nodes from hash table. If free_collisions is TRUE, the
    memory allocated from node_pool is freed, or discarded with
    alloconly pools. */
--- a/src/lib/ioloop-notify-dn.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/ioloop-notify-dn.c	Sat Jan 14 20:47:20 2006 +0200
@@ -143,10 +143,8 @@
 
 	p_free(ioloop->pool, io);
 
-	if (ioloop->notifys == NULL) {
-		io_remove(ctx->event_io);
-		ctx->event_io = NULL;
-	}
+	if (ioloop->notifys == NULL)
+		io_remove(&ctx->event_io);
 }
 
 void io_loop_notify_handler_init(struct ioloop *ioloop)
--- a/src/lib/ioloop.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/ioloop.c	Sat Jan 14 20:47:20 2006 +0200
@@ -56,8 +56,12 @@
 	return io;
 }
 
-void io_remove(struct io *io)
+void io_remove(struct io **_io)
 {
+	struct io *io = *_io;
+
+	*_io = NULL;
+
 	if ((io->condition & IO_NOTIFY) != 0) {
 		io_loop_notify_remove(current_ioloop, io);
 		return;
@@ -134,11 +138,12 @@
 	return timeout;
 }
 
-void timeout_remove(struct timeout *timeout)
+void timeout_remove(struct timeout **timeout)
 {
-	i_assert(timeout != NULL);
+	i_assert(*timeout != NULL);
 
-	timeout->destroyed = TRUE;
+	(*timeout)->destroyed = TRUE;
+	*timeout = NULL;
 }
 
 void timeout_destroy(struct ioloop *ioloop, struct timeout **timeout_p)
@@ -267,15 +272,18 @@
         return ioloop;
 }
 
-void io_loop_destroy(struct ioloop *ioloop)
+void io_loop_destroy(struct ioloop **_ioloop)
 {
+        struct ioloop *ioloop = *_ioloop;
 	pool_t pool;
 
+	*_ioloop = NULL;
+
 	while (ioloop->ios != NULL) {
 		struct io *io = ioloop->ios;
 
 		i_warning("I/O leak: %p (%d)", (void *)io->callback, io->fd);
-		io_remove(io);
+		io_remove(&io);
 	}
 
 	while (ioloop->timeouts != NULL) {
@@ -283,7 +291,7 @@
 
 		if (!to->destroyed) {
 			i_warning("Timeout leak: %p", (void *)to->callback);
-			timeout_remove(to);
+			timeout_remove(&to);
 		}
                 timeout_destroy(ioloop, &ioloop->timeouts);
 	}
--- a/src/lib/ioloop.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/ioloop.h	Sat Jan 14 20:47:20 2006 +0200
@@ -37,12 +37,14 @@
 		  io_callback_t *callback, void *context);
 struct io *io_add_notify(const char *path, io_callback_t *callback,
 			 void *context);
-void io_remove(struct io *io);
+/* Remove I/O handler, and set io pointer to NULL. */
+void io_remove(struct io **io);
 
 /* Timeout handlers */
 struct timeout *timeout_add(unsigned int msecs, timeout_callback_t *callback,
 			    void *context);
-void timeout_remove(struct timeout *timeout);
+/* Remove timeout handler, and set timeout pointer to NULL. */
+void timeout_remove(struct timeout **timeout);
 
 void io_loop_run(struct ioloop *ioloop);
 void io_loop_stop(struct ioloop *ioloop); /* safe to run in signal handler */
@@ -54,6 +56,7 @@
 void io_loop_handler_run(struct ioloop *ioloop);
 
 struct ioloop *io_loop_create(pool_t pool);
-void io_loop_destroy(struct ioloop *ioloop);
+/* Destroy I/O loop and set ioloop pointer to NULL. */
+void io_loop_destroy(struct ioloop **ioloop);
 
 #endif
--- a/src/lib/istream-limit.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/istream-limit.c	Sat Jan 14 20:47:20 2006 +0200
@@ -21,7 +21,7 @@
 	/* get to same position in parent stream */
 	i_stream_seek(lstream->input, lstream->v_start_offset +
 		      lstream->istream.istream.v_offset);
-	i_stream_unref(lstream->input);
+	i_stream_unref(&lstream->input);
 }
 
 static void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
--- a/src/lib/istream-seekable.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/istream-seekable.c	Sat Jan 14 20:47:20 2006 +0200
@@ -50,9 +50,9 @@
 	if (sstream->buffer != NULL)
 		buffer_free(sstream->buffer);
 	if (sstream->fd_input != NULL)
-		i_stream_unref(sstream->fd_input);
+		i_stream_unref(&sstream->fd_input);
 	for (i = 0; sstream->input[i] != NULL; i++)
-		i_stream_unref(sstream->input[i]);
+		i_stream_unref(&sstream->input[i]);
 
 	p_free(sstream->pool, sstream->temp_prefix);
 	pool_unref(sstream->pool);
--- a/src/lib/istream.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/istream.c	Sat Jan 14 20:47:20 2006 +0200
@@ -10,15 +10,16 @@
 	_io_stream_ref(&stream->real_stream->iostream);
 }
 
-void i_stream_unref(struct istream *stream)
+void i_stream_unref(struct istream **stream)
 {
-	struct _istream *_stream = stream->real_stream;
+	struct _istream *_stream = (*stream)->real_stream;
 
 	if (_stream->iostream.refcount == 1) {
 		if (_stream->line_str != NULL)
-			str_free(_stream->line_str);
+			str_free(&_stream->line_str);
 	}
-	_io_stream_unref(&stream->real_stream->iostream);
+	_io_stream_unref(&(*stream)->real_stream->iostream);
+	*stream = NULL;
 }
 
 int i_stream_get_fd(struct istream *stream)
--- a/src/lib/istream.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/istream.h	Sat Jan 14 20:47:20 2006 +0200
@@ -27,7 +27,8 @@
 /* Reference counting. References start from 1, so calling i_stream_unref()
    destroys the stream if i_stream_ref() is never used. */
 void i_stream_ref(struct istream *stream);
-void i_stream_unref(struct istream *stream);
+/* Unreferences the stream and sets stream pointer to NULL. */
+void i_stream_unref(struct istream **stream);
 
 /* Return file descriptor for stream, or -1 if none is available. */
 int i_stream_get_fd(struct istream *stream);
--- a/src/lib/lib-signals.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/lib-signals.c	Sat Jan 14 20:47:20 2006 +0200
@@ -186,7 +186,7 @@
 	}
 
 	if (io_sig != NULL)
-		io_remove(io_sig);
+		io_remove(&io_sig);
 	if (sig_pipe_fd[0] != -1) {
 		if (close(sig_pipe_fd[0]) < 0)
 			i_error("close(sigpipe) failed: %m");
--- a/src/lib/module-dir.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/module-dir.c	Sat Jan 14 20:47:20 2006 +0200
@@ -187,15 +187,16 @@
 	return modules;
 }
 
-void module_dir_unload(struct module *modules)
+void module_dir_unload(struct module **modules)
 {
-	struct module *next;
+	struct module *module, *next;
 
-	while (modules != NULL) {
-		next = modules->next;
-		module_free(modules);
-		modules = next;
+	for (module = *modules; module != NULL; module = next) {
+		next = module->next;
+		module_free(module);
 	}
+
+	*modules = NULL;
 }
 
 #else
--- a/src/lib/module-dir.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/module-dir.h	Sat Jan 14 20:47:20 2006 +0200
@@ -13,7 +13,7 @@
 /* Load all modules in given directory. */
 struct module *module_dir_load(const char *dir, bool require_init_funcs);
 /* Unload all modules */
-void module_dir_unload(struct module *modules);
+void module_dir_unload(struct module **modules);
 
 void *module_get_symbol(struct module *module, const char *symbol);
 
--- a/src/lib/ostream-crlf.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/ostream-crlf.c	Sat Jan 14 20:47:20 2006 +0200
@@ -28,7 +28,7 @@
 {
 	struct crlf_ostream *cstream = (struct crlf_ostream *)stream;
 
-	o_stream_unref(cstream->output);
+	o_stream_unref(&cstream->output);
 }
 
 static void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
--- a/src/lib/ostream-file.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/ostream-file.c	Sat Jan 14 20:47:20 2006 +0200
@@ -57,10 +57,8 @@
 		fstream->fd = -1;
 	}
 
-	if (fstream->io != NULL) {
-		io_remove(fstream->io);
-		fstream->io = NULL;
-	}
+	if (fstream->io != NULL)
+		io_remove(&fstream->io);
 
 	fstream->ostream.ostream.closed = TRUE;
 }
@@ -215,10 +213,9 @@
 	int ret;
 
 	if (fstream->corked != set && !stream->ostream.closed) {
-		if (set && fstream->io != NULL) {
-			io_remove(fstream->io);
-			fstream->io = NULL;
-		} else if (!set) {
+		if (set && fstream->io != NULL)
+			io_remove(&fstream->io);
+		else if (!set) {
 			ret = buffer_flush(fstream);
 			if (fstream->io == NULL &&
 			    (ret == 0 || fstream->flush_pending)) {
@@ -343,6 +340,7 @@
 static void stream_send_io(void *context)
 {
 	struct file_ostream *fstream = context;
+	struct ostream *ostream = &fstream->ostream.ostream;
 	int ret;
 
 	/* Set flush_pending = FALSE first before calling the flush callback,
@@ -351,7 +349,7 @@
 	   forget it even if flush callback returns 1. */
 	fstream->flush_pending = FALSE;
 
-	o_stream_ref(&fstream->ostream.ostream);
+	o_stream_ref(ostream);
 	if (fstream->ostream.callback != NULL)
 		ret = fstream->ostream.callback(fstream->ostream.context);
 	else
@@ -363,8 +361,7 @@
 	if (!fstream->flush_pending && IS_STREAM_EMPTY(fstream)) {
 		if (fstream->io != NULL) {
 			/* all sent */
-			io_remove(fstream->io);
-			fstream->io = NULL;
+			io_remove(&fstream->io);
 		}
 	} else {
 		/* Add the IO handler if it's not there already. Callback
@@ -376,7 +373,7 @@
 		}
 	}
 
-	o_stream_unref(&fstream->ostream.ostream);
+	o_stream_unref(&ostream);
 }
 
 static size_t o_stream_add(struct file_ostream *fstream,
--- a/src/lib/ostream.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/ostream.c	Sat Jan 14 20:47:20 2006 +0200
@@ -9,9 +9,10 @@
 	_io_stream_ref(&stream->real_stream->iostream);
 }
 
-void o_stream_unref(struct ostream *stream)
+void o_stream_unref(struct ostream **stream)
 {
-	_io_stream_unref(&stream->real_stream->iostream);
+	_io_stream_unref(&(*stream)->real_stream->iostream);
+	*stream = NULL;
 }
 
 void o_stream_close(struct ostream *stream)
--- a/src/lib/ostream.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/ostream.h	Sat Jan 14 20:47:20 2006 +0200
@@ -30,7 +30,8 @@
 /* Reference counting. References start from 1, so calling o_stream_unref()
    destroys the stream if o_stream_ref() is never used. */
 void o_stream_ref(struct ostream *stream);
-void o_stream_unref(struct ostream *stream);
+/* Unreferences the stream and sets stream pointer to NULL. */
+void o_stream_unref(struct ostream **stream);
 
 /* Mark the stream closed. Nothing will be sent after this call. */
 void o_stream_close(struct ostream *stream);
--- a/src/lib/str.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/str.c	Sat Jan 14 20:47:20 2006 +0200
@@ -17,9 +17,9 @@
 	return str_new(pool_datastack_create(), initial_size);
 }
 
-void str_free(string_t *str)
+void str_free(string_t **str)
 {
-	buffer_free(str);
+	buffer_free(*str);
 }
 
 static void str_add_nul(string_t *str)
@@ -33,10 +33,10 @@
 	buffer_set_used_size(str, len);
 }
 
-char *str_free_without_data(string_t *str)
+char *str_free_without_data(string_t **str)
 {
-	str_add_nul(str);
-	return buffer_free_without_data(str);
+	str_add_nul(*str);
+	return buffer_free_without_data(*str);
 }
 
 const char *str_c(string_t *str)
--- a/src/lib/str.h	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/lib/str.h	Sat Jan 14 20:47:20 2006 +0200
@@ -3,8 +3,8 @@
 
 string_t *str_new(pool_t pool, size_t initial_size);
 string_t *t_str_new(size_t initial_size);
-void str_free(string_t *str);
-char *str_free_without_data(string_t *str);
+void str_free(string_t **str);
+char *str_free_without_data(string_t **str);
 
 const char *str_c(string_t *str);
 const unsigned char *str_data(const string_t *str);
--- a/src/login-common/login-proxy.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/login-common/login-proxy.c	Sat Jan 14 20:47:20 2006 +0200
@@ -38,7 +38,7 @@
 	    OUTBUF_THRESHOLD) {
 		/* client's output buffer is already quite full.
 		   don't send more until we're below threshold. */
-		io_remove(proxy->server_io);
+		io_remove(&proxy->server_io);
 		proxy->server_io = NULL;
 		return;
 	}
@@ -60,7 +60,7 @@
 	    OUTBUF_THRESHOLD) {
 		/* proxy's output buffer is already quite full.
 		   don't send more until we're below threshold. */
-		io_remove(proxy->client_io);
+		io_remove(&proxy->client_io);
 		proxy->client_io = NULL;
 		return;
 	}
@@ -141,7 +141,7 @@
 		o_stream_create_file(proxy->server_fd, default_pool,
 				     (size_t)-1, FALSE);
 
-	io_remove(proxy->server_io);
+	io_remove(&proxy->server_io);
 	proxy->server_io =
 		io_add(proxy->server_fd, IO_READ, proxy_prelogin_input, proxy);
 }
@@ -205,9 +205,9 @@
 		       proxy->user, net_ip2addr(&ip));
 
 		if (proxy->client_io != NULL)
-			io_remove(proxy->client_io);
+			io_remove(&proxy->client_io);
 		if (proxy->client_output != NULL)
-			o_stream_unref(proxy->client_output);
+			o_stream_unref(&proxy->client_output);
 		net_disconnect(proxy->client_fd);
 	} else {
 		proxy->destroying = TRUE;
@@ -215,11 +215,11 @@
 	}
 
 	if (proxy->server_io != NULL)
-		io_remove(proxy->server_io);
+		io_remove(&proxy->server_io);
 	if (proxy->server_input != NULL)
-		i_stream_unref(proxy->server_input);
+		i_stream_unref(&proxy->server_input);
 	if (proxy->server_output != NULL)
-		o_stream_unref(proxy->server_output);
+		o_stream_unref(&proxy->server_output);
 	net_disconnect(proxy->server_fd);
 
 	i_free(proxy->host);
@@ -243,16 +243,16 @@
 	data = i_stream_get_data(client_input, &size);
 	if (size != 0)
 		(void)o_stream_send(proxy->server_output, data, size);
-	i_stream_unref(client_input);
+	i_stream_unref(&client_input);
 
 	/* from now on, just do dummy proxying */
-	io_remove(proxy->server_io);
+	io_remove(&proxy->server_io);
 	proxy->server_io = io_add(proxy->server_fd, IO_READ, server_input, proxy);
 	proxy->client_io = io_add(proxy->client_fd, IO_READ,
 				  proxy_client_input, proxy);
 	o_stream_set_flush_callback(proxy->server_output, server_output, proxy);
 
-	i_stream_unref(proxy->server_input);
+	i_stream_unref(&proxy->server_input);
         proxy->server_input = NULL;
 
 	if (login_proxies == NULL) {
--- a/src/login-common/main.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/login-common/main.c	Sat Jan 14 20:47:20 2006 +0200
@@ -58,16 +58,14 @@
 		if (close(LOGIN_LISTEN_FD) < 0)
 			i_fatal("close(listen) failed: %m");
 
-		io_remove(io_listen);
-		io_listen = NULL;
+		io_remove(&io_listen);
 	}
 
 	if (io_ssl_listen != NULL) {
 		if (close(LOGIN_SSL_LISTEN_FD) < 0)
 			i_fatal("close(ssl_listen) failed: %m");
 
-		io_remove(io_ssl_listen);
-		io_ssl_listen = NULL;
+		io_remove(&io_ssl_listen);
 	}
 
 	closing_down = TRUE;
@@ -247,13 +245,13 @@
 
 static void main_deinit(void)
 {
-	if (io_listen != NULL) io_remove(io_listen);
-	if (io_ssl_listen != NULL) io_remove(io_ssl_listen);
+	if (io_listen != NULL) io_remove(&io_listen);
+	if (io_ssl_listen != NULL) io_remove(&io_ssl_listen);
 
 	ssl_proxy_deinit();
 	login_proxy_deinit();
 
-	auth_client_free(auth_client);
+	auth_client_free(&auth_client);
 	clients_deinit();
 	master_deinit();
 
@@ -343,7 +341,7 @@
 	io_loop_run(ioloop);
 	main_deinit();
 
-	io_loop_destroy(ioloop);
+	io_loop_destroy(&ioloop);
 	lib_deinit();
 
         return 0;
--- a/src/login-common/master.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/login-common/master.c	Sat Jan 14 20:47:20 2006 +0200
@@ -97,8 +97,7 @@
 		i_fatal("close(master) failed: %m");
 	master_fd = -1;
 
-	io_remove(io_master);
-	io_master = NULL;
+	io_remove(&io_master);
 
         main_close_listen();
 	main_unref();
@@ -153,7 +152,7 @@
 			env_put(line);
 	} while (line == NULL);
 
-	i_stream_unref(input);
+	i_stream_unref(&input);
 }
 
 int master_connect(const char *group_name)
@@ -248,5 +247,5 @@
 	hash_destroy(master_requests);
 
 	if (io_master != NULL)
-		io_remove(io_master);
+		io_remove(&io_master);
 }
--- a/src/login-common/ssl-proxy-openssl.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/login-common/ssl-proxy-openssl.c	Sat Jan 14 20:47:20 2006 +0200
@@ -66,10 +66,8 @@
 					    ssl_step, proxy);
 		break;
 	case SSL_REMOVE_INPUT:
-		if (proxy->io_ssl_read != NULL) {
-			io_remove(proxy->io_ssl_read);
-			proxy->io_ssl_read = NULL;
-		}
+		if (proxy->io_ssl_read != NULL)
+			io_remove(&proxy->io_ssl_read);
 		break;
 	case SSL_ADD_OUTPUT:
 		if (proxy->io_ssl_write != NULL)
@@ -78,10 +76,8 @@
 					     ssl_step, proxy);
 		break;
 	case SSL_REMOVE_OUTPUT:
-		if (proxy->io_ssl_write != NULL) {
-			io_remove(proxy->io_ssl_write);
-			proxy->io_ssl_write = NULL;
-		}
+		if (proxy->io_ssl_write != NULL)
+			io_remove(&proxy->io_ssl_write);
 		break;
 	}
 }
@@ -89,10 +85,8 @@
 static void plain_block_input(struct ssl_proxy *proxy, bool block)
 {
 	if (block) {
-		if (proxy->io_plain_read != NULL) {
-			io_remove(proxy->io_plain_read);
-			proxy->io_plain_read = NULL;
-		}
+		if (proxy->io_plain_read != NULL)
+			io_remove(&proxy->io_plain_read);
 	} else {
 		if (proxy->io_plain_read == NULL) {
 			proxy->io_plain_read = io_add(proxy->fd_plain, IO_READ,
@@ -164,10 +158,8 @@
 					       plain_write, proxy);
 			}
 		} else {
-			if (proxy->io_plain_write != NULL) {
-				io_remove(proxy->io_plain_write);
-                                proxy->io_plain_write = NULL;
-			}
+			if (proxy->io_plain_write != NULL)
+				io_remove(&proxy->io_plain_write);
 		}
 
 		ssl_set_io(proxy, SSL_ADD_INPUT);
@@ -428,13 +420,13 @@
 	(void)net_disconnect(proxy->fd_plain);
 
 	if (proxy->io_ssl_read != NULL)
-		io_remove(proxy->io_ssl_read);
+		io_remove(&proxy->io_ssl_read);
 	if (proxy->io_ssl_write != NULL)
-		io_remove(proxy->io_ssl_write);
+		io_remove(&proxy->io_ssl_write);
 	if (proxy->io_plain_read != NULL)
-		io_remove(proxy->io_plain_read);
+		io_remove(&proxy->io_plain_read);
 	if (proxy->io_plain_write != NULL)
-		io_remove(proxy->io_plain_write);
+		io_remove(&proxy->io_plain_write);
 
 	ssl_proxy_unref(proxy);
 }
--- a/src/master/auth-process.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/master/auth-process.c	Sat Jan 14 20:47:20 2006 +0200
@@ -347,7 +347,7 @@
 
 	if (close(p->worker_listen_fd) < 0)
 		i_error("close(worker_listen) failed: %m");
-	io_remove(p->worker_io);
+	io_remove(&p->worker_io);
 
 	iter = hash_iterate_init(p->requests);
 	while (hash_iterate(iter, &key, &value))
@@ -355,9 +355,9 @@
 	hash_iterate_deinit(iter);
 	hash_destroy(p->requests);
 
-	i_stream_unref(p->input);
-	o_stream_unref(p->output);
-	io_remove(p->io);
+	i_stream_unref(&p->input);
+	o_stream_unref(&p->output);
+	io_remove(&p->io);
 	if (close(p->fd) < 0)
 		i_error("close(auth) failed: %m");
 	i_free(p);
@@ -738,6 +738,6 @@
 
 void auth_processes_deinit(void)
 {
-	timeout_remove(to);
+	timeout_remove(&to);
 	auth_processes_destroy_all();
 }
--- a/src/master/dict-process.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/master/dict-process.c	Sat Jan 14 20:47:20 2006 +0200
@@ -142,8 +142,7 @@
 		i_error("close(dict) failed: %m");
 	process->fd = -1;
 
-	io_remove(process->io);
-	process->io = NULL;
+	io_remove(&process->io);
 }
 
 void dict_process_init(void)
--- a/src/master/log.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/master/log.c	Sat Jan 14 20:47:20 2006 +0200
@@ -57,10 +57,8 @@
 		       FALSE);
 	}
 
-	if (log_io->io != NULL) {
-		io_remove(log_io->io);
-		log_io->io = NULL;
-	}
+	if (log_io->io != NULL)
+		io_remove(&log_io->io);
 
 	if (to == NULL)
 		to = timeout_add(1000, log_throttle_timeout, NULL);
@@ -72,10 +70,8 @@
 	if (log_io->io != NULL)
 		return;
 
-	if (--throttle_count == 0 && to != NULL) {
-		timeout_remove(to);
-		to = NULL;
-	}
+	if (--throttle_count == 0 && to != NULL)
+		timeout_remove(&to);
 	log_io->io = io_add(i_stream_get_fd(log_io->stream),
 			    IO_READ, log_read, log_io);
 }
@@ -218,10 +214,10 @@
 		log_io->next->prev = log_io->prev;
 
 	if (log_io->io != NULL)
-		io_remove(log_io->io);
+		io_remove(&log_io->io);
 	else
 		throttle_count--;
-	i_stream_unref(log_io->stream);
+	i_stream_unref(&log_io->stream);
 	i_free(log_io->prefix);
 	i_free(log_io);
 }
@@ -264,5 +260,5 @@
 	}
 
 	if (to != NULL)
-		timeout_remove(to);
+		timeout_remove(&to);
 }
--- a/src/master/login-process.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/master/login-process.c	Sat Jan 14 20:47:20 2006 +0200
@@ -361,7 +361,7 @@
 		p->group->listening_processes--;
 
 	o_stream_close(p->output);
-	io_remove(p->io);
+	io_remove(&p->io);
 	if (close(p->fd) < 0)
 		i_error("close(login) failed: %m");
 
@@ -382,7 +382,7 @@
 	if (--p->refcount > 0)
 		return;
 
-	o_stream_unref(p->output);
+	o_stream_unref(&p->output);
 	i_free(p);
 }
 
@@ -718,9 +718,9 @@
 void login_processes_deinit(void)
 {
 	if (to != NULL)
-		timeout_remove(to);
+		timeout_remove(&to);
 	if (io_listen != NULL)
-		io_remove(io_listen);
+		io_remove(&io_listen);
 
         login_processes_destroy_all();
 	hash_destroy(processes);
--- a/src/master/main.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/master/main.c	Sat Jan 14 20:47:20 2006 +0200
@@ -569,7 +569,7 @@
 	dict_process_deinit();
 	ssl_deinit();
 
-	timeout_remove(to);
+	timeout_remove(&to);
 
 	if (close(null_fd) < 0)
 		i_error("close(null_fd) failed: %m");
@@ -776,7 +776,7 @@
 	main_deinit();
 
 	master_settings_deinit();
-	io_loop_destroy(ioloop);
+	io_loop_destroy(&ioloop);
 	lib_deinit();
 
         return 0;
--- a/src/master/ssl-init.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/master/ssl-init.c	Sat Jan 14 20:47:20 2006 +0200
@@ -123,7 +123,7 @@
 
 void ssl_deinit(void)
 {
-	timeout_remove(to);
+	timeout_remove(&to);
 }
 
 #else
--- a/src/plugins/imap-quota/imap-quota-plugin.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/plugins/imap-quota/imap-quota-plugin.c	Sat Jan 14 20:47:20 2006 +0200
@@ -103,7 +103,7 @@
 			"* BAD ", quota_last_error(quota), NULL));
 	}
 
-	mailbox_close(box);
+	mailbox_close(&box);
 
 	client_send_tagline(cmd, "OK Getquotaroot completed.");
 	return TRUE;
--- a/src/plugins/quota/quota-storage.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/plugins/quota/quota-storage.c	Sat Jan 14 20:47:20 2006 +0200
@@ -148,7 +148,7 @@
 	ret = qbox->save_hack ? 0 : quota_check(t, copy_dest_mail);
 
 	if (copy_dest_mail != dest_mail)
-		mail_free(copy_dest_mail);
+		mail_free(&copy_dest_mail);
 	return ret;
 }
 
@@ -196,7 +196,7 @@
 	ret = quota_check(ctx->transaction, save_dest_mail);
 
 	if (save_dest_mail != dest_mail)
-		mail_free(save_dest_mail);
+		mail_free(&save_dest_mail);
 	return ret;
 }
 
--- a/src/plugins/trash/trash-plugin.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/plugins/trash/trash-plugin.c	Sat Jan 14 20:47:20 2006 +0200
@@ -146,23 +146,18 @@
 	for (i = 0; i < count; i++) {
 		struct trash_mailbox *trash = &trashes[i];
 
-		mail_free(trash->mail);
-		trash->mail = NULL;
-
-		(void)mailbox_search_deinit(trash->search_ctx);
-		trash->search_ctx = NULL;
+		mail_free(&trash->mail);
+		(void)mailbox_search_deinit(&trash->search_ctx);
 
 		if (size_needed == 0) {
-			(void)mailbox_transaction_commit(trash->trans,
+			(void)mailbox_transaction_commit(&trash->trans,
 				MAILBOX_SYNC_FLAG_FULL_WRITE);
 		} else {
 			/* couldn't get enough space, don't expunge anything */
-                        mailbox_transaction_rollback(trash->trans);
+                        mailbox_transaction_rollback(&trash->trans);
 		}
-		trash->trans = NULL;
 
-		mailbox_close(trash->box);
-		trash->box = NULL;
+		mailbox_close(&trash->box);
 	}
 	return size_needed == 0;
 }
@@ -265,7 +260,7 @@
 		trash->name = p_strdup(config_pool, name+1);
 		trash->priority = atoi(t_strdup_until(line, name));
 	}
-	i_stream_unref(input);
+	i_stream_unref(&input);
 	(void)close(fd);
 
 	qsort(array_get_modifyable(&trash_boxes, NULL),
--- a/src/plugins/zlib/zlib-plugin.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/plugins/zlib/zlib-plugin.c	Sat Jan 14 20:47:20 2006 +0200
@@ -57,7 +57,7 @@
 	box = qstorage->super.mailbox_open(storage, name, input, flags);
 
 	if (zlib_input != NULL)
-		i_stream_unref(zlib_input);
+		i_stream_unref(&zlib_input);
 
 	return box;
 }
--- a/src/pop3-login/client-authenticate.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/pop3-login/client-authenticate.c	Sat Jan 14 20:47:20 2006 +0200
@@ -138,7 +138,7 @@
 
 	/* get back to normal client input. */
 	if (client->io != NULL)
-		io_remove(client->io);
+		io_remove(&client->io);
 	client->io = io_add(client->common.fd, IO_READ,
 			    client_input, client);
 	return TRUE;
@@ -172,7 +172,7 @@
 
 		/* get back to normal client input. */
 		if (client->io != NULL)
-			io_remove(client->io);
+			io_remove(&client->io);
 		client->io = io_add(client->common.fd, IO_READ,
 				    client_input, client);
 		break;
@@ -242,7 +242,7 @@
 
 	/* following input data will go to authentication */
 	if (client->io != NULL)
-		io_remove(client->io);
+		io_remove(&client->io);
 	client->io = io_add(client->common.fd, IO_READ,
 			    client_auth_input, client);
 	return TRUE;
@@ -297,10 +297,8 @@
 		return TRUE;
 
 	/* don't read any input from client until login is finished */
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
+	if (client->io != NULL)
+		io_remove(&client->io);
 	return TRUE;
 }
 
@@ -357,9 +355,7 @@
 		return TRUE;
 
 	/* don't read any input from client until login is finished */
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
+	if (client->io != NULL)
+		io_remove(&client->io);
 	return TRUE;
 }
--- a/src/pop3-login/client.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/pop3-login/client.c	Sat Jan 14 20:47:20 2006 +0200
@@ -87,8 +87,8 @@
 
 	client->common.fd = fd_ssl;
 
-	i_stream_unref(client->input);
-	o_stream_unref(client->output);
+	i_stream_unref(&client->input);
+	o_stream_unref(&client->output);
 
 	client_open_streams(client, fd_ssl);
 	client->io = io_add(client->common.fd, IO_READ, client_input, client);
@@ -123,10 +123,8 @@
 
 	/* remove input handler, SSL proxy gives us a new fd. we also have to
 	   remove it in case we have to wait for buffer to be flushed */
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
+	if (client->io != NULL)
+		io_remove(&client->io);
 
 	client_send_line(client, "+OK Begin TLS negotiation now.");
 
@@ -366,10 +364,8 @@
 	if (client->common.master_tag != 0)
 		master_request_abort(&client->common);
 
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
+	if (client->io != NULL)
+		io_remove(&client->io);
 
 	if (client->common.fd != -1) {
 		net_disconnect(client->common.fd);
@@ -414,9 +410,9 @@
 		return TRUE;
 
 	if (client->input != NULL)
-		i_stream_unref(client->input);
+		i_stream_unref(&client->input);
 	if (client->output != NULL)
-		o_stream_unref(client->output);
+		o_stream_unref(&client->output);
 
 	i_free(client->last_user);
 	i_free(client->apop_challenge);
@@ -515,5 +511,5 @@
 	clients_destroy_all();
 	hash_destroy(clients);
 
-	timeout_remove(to_idle);
+	timeout_remove(&to_idle);
 }
--- a/src/pop3-login/pop3-proxy.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/pop3-login/pop3-proxy.c	Sat Jan 14 20:47:20 2006 +0200
@@ -153,10 +153,7 @@
 	client->proxy_password = i_strdup(password);
 
 	/* disable input until authentication is finished */
-	if (client->io != NULL) {
-		io_remove(client->io);
-		client->io = NULL;
-	}
-
+	if (client->io != NULL)
+		io_remove(&client->io);
 	return 0;
 }
--- a/src/pop3/client.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/pop3/client.c	Sat Jan 14 20:47:20 2006 +0200
@@ -46,7 +46,7 @@
 	ctx = mailbox_sync_init(box, MAILBOX_SYNC_FLAG_FULL_READ);
 	while (mailbox_sync_next(ctx, &sync_rec) > 0)
 		;
-	return mailbox_sync_deinit(ctx, status);
+	return mailbox_sync_deinit(&ctx, status);
 }
 
 static int init_mailbox(struct client *client)
@@ -76,7 +76,7 @@
 		ctx = mailbox_search_init(t, NULL, &search_arg, NULL);
 		if (ctx == NULL) {
 			client_send_storage_error(client);
-			mailbox_transaction_rollback(t);
+			mailbox_transaction_rollback(&t);
 			break;
 		}
 
@@ -103,10 +103,10 @@
 		client->messages_count =
 			message_sizes_buf->used / sizeof(uoff_t);
 
-		mail_free(mail);
-		if (mailbox_search_deinit(ctx) < 0) {
+		mail_free(&mail);
+		if (mailbox_search_deinit(&ctx) < 0) {
 			client_send_storage_error(client);
-			mailbox_transaction_rollback(t);
+			mailbox_transaction_rollback(&t);
 			break;
 		}
 
@@ -118,7 +118,7 @@
 		}
 
 		/* well, sync and try again */
-		mailbox_transaction_rollback(t);
+		mailbox_transaction_rollback(&t);
 	}
 
 	if (i == 2)
@@ -220,19 +220,19 @@
 		i_assert(client->cmd == NULL);
 	}
 	if (client->trans != NULL)
-		mailbox_transaction_rollback(client->trans);
+		mailbox_transaction_rollback(&client->trans);
 	if (client->mailbox != NULL)
-		mailbox_close(client->mailbox);
-	mail_storage_destroy(client->storage);
+		mailbox_close(&client->mailbox);
+	mail_storage_destroy(&client->storage);
 
 	i_free(client->message_sizes);
 	i_free(client->deleted_bitmask);
 
 	if (client->io != NULL)
-		io_remove(client->io);
+		io_remove(&client->io);
 
-	i_stream_unref(client->input);
-	o_stream_unref(client->output);
+	i_stream_unref(&client->input);
+	o_stream_unref(&client->output);
 
 	i_free(client);
 
@@ -281,8 +281,7 @@
 			if (client->io != NULL) {
 				/* no more input until client has read
 				   our output */
-				io_remove(client->io);
-				client->io = NULL;
+				io_remove(&client->io);
 
 				/* If someone happens to flush output,
 				   we want to get our IO handler back in
@@ -325,8 +324,7 @@
 	if (client->cmd != NULL) {
 		/* we're still processing a command. wait until it's
 		   finished. */
-		io_remove(client->io);
-		client->io = NULL;
+		io_remove(&client->io);
 		client->waiting_input = TRUE;
 		return;
 	}
@@ -441,5 +439,5 @@
 		client_destroy(my_client, "Server shutting down.");
 	}
 
-	timeout_remove(to_idle);
+	timeout_remove(&to_idle);
 }
--- a/src/pop3/commands.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/pop3/commands.c	Sat Jan 14 20:47:20 2006 +0200
@@ -213,9 +213,9 @@
 			}
 		}
 	}
-	mail_free(mail);
+	mail_free(&mail);
 
-	if (mailbox_search_deinit(ctx) < 0)
+	if (mailbox_search_deinit(&ctx) < 0)
 		ret = FALSE;
 	return ret;
 }
@@ -231,8 +231,8 @@
 		}
 	}
 
-	mailbox_transaction_commit(client->trans, MAILBOX_SYNC_FLAG_FULL_WRITE);
-	client->trans = NULL;
+	mailbox_transaction_commit(&client->trans,
+				   MAILBOX_SYNC_FLAG_FULL_WRITE);
 
 	if (!client->deleted)
 		client_send_line(client, "+OK Logging out.");
@@ -258,8 +258,8 @@
 
 static void fetch_deinit(struct fetch_context *ctx)
 {
-	(void)mailbox_search_deinit(ctx->search_ctx);
-	mail_free(ctx->mail);
+	(void)mailbox_search_deinit(&ctx->search_ctx);
+	mail_free(&ctx->mail);
 	i_free(ctx);
 }
 
@@ -443,7 +443,7 @@
 	}
 
 	/* forget all our seen flag updates as well.. */
-	mailbox_transaction_rollback(client->trans);
+	mailbox_transaction_rollback(&client->trans);
 	client->trans = mailbox_transaction_begin(client->mailbox, 0);
 
 	if (enable_last_command) {
@@ -463,8 +463,8 @@
 					      MAIL_SEEN) < 0)
 				break;
 		}
-		mail_free(mail);
-		(void)mailbox_search_deinit(search_ctx);
+		mail_free(&mail);
+		(void)mailbox_search_deinit(&search_ctx);
 	}
 
 	client_send_line(client, "+OK");
@@ -579,15 +579,15 @@
 		if (ret == 0 && ctx->message == 0) {
 			/* output is being buffered, continue when there's
 			   more space */
-			str_free(str);
+			str_free(&str);
 			return 0;
 		}
 	}
-	str_free(str);
+	str_free(&str);
 
 	/* finished */
-	mail_free(ctx->mail);
-	(void)mailbox_search_deinit(ctx->search_ctx);
+	mail_free(&ctx->mail);
+	(void)mailbox_search_deinit(&ctx->search_ctx);
 
 	client->cmd = NULL;
 
--- a/src/pop3/main.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/pop3/main.c	Sat Jan 14 20:47:20 2006 +0200
@@ -251,7 +251,7 @@
 
 static void main_deinit(void)
 {
-	module_dir_unload(modules);
+	module_dir_unload(&modules);
 
 	clients_deinit();
         mail_storage_deinit();
@@ -287,7 +287,7 @@
 		io_loop_run(ioloop);
 	main_deinit();
 
-	io_loop_destroy(ioloop);
+	io_loop_destroy(&ioloop);
 	lib_deinit();
 
 	return 0;
--- a/src/util/rawlog.c	Sat Jan 14 19:23:22 2006 +0200
+++ b/src/util/rawlog.c	Sat Jan 14 20:47:20 2006 +0200
@@ -48,13 +48,13 @@
 			i_error("close(out) failed: %m");
 	}
 	if (proxy->client_io != NULL)
-		io_remove(proxy->client_io);
+		io_remove(&proxy->client_io);
 	if (proxy->server_io != NULL)
-		io_remove(proxy->server_io);
+		io_remove(&proxy->server_io);
 
-	i_stream_unref(proxy->server_input);
-	o_stream_unref(proxy->client_output);
-	o_stream_unref(proxy->server_output);
+	i_stream_unref(&proxy->server_input);
+	o_stream_unref(&proxy->client_output);
+	o_stream_unref(&proxy->server_output);
 
 	if (close(proxy->client_in_fd) < 0)
 		i_error("close(client_in_fd) failed: %m");
@@ -121,8 +121,7 @@
 	    OUTBUF_THRESHOLD) {
 		/* client's output buffer is already quite full.
 		   don't send more until we're below threshold. */
-		io_remove(proxy->server_io);
-		proxy->server_io = NULL;
+		io_remove(&proxy->server_io);
 		return;
 	}
 
@@ -144,8 +143,7 @@
 	    OUTBUF_THRESHOLD) {
 		/* proxy's output buffer is already quite full.
 		   don't send more until we're below threshold. */
-		io_remove(proxy->client_io);
-		proxy->client_io = NULL;
+		io_remove(&proxy->client_io);
 		return;
 	}
 
@@ -309,7 +307,7 @@
 	ioloop = io_loop_create(system_pool);
 	rawlog_proxy_create(0, 1, sfd[0], path, write_timestamps);
 	io_loop_run(ioloop);
-	io_loop_destroy(ioloop);
+	io_loop_destroy(&ioloop);
 
 	lib_deinit();
 	exit(0);