diff -r -U4 irssi-0.8.13/src/core/chat-commands.c irssi-0.8.13+autosession/src/core/chat-commands.c
--- irssi-0.8.13/src/core/chat-commands.c	2009-03-31 22:02:51.000000000 +0100
+++ irssi-0.8.13+autosession/src/core/chat-commands.c	2009-07-05 11:44:58.000000000 +0100
@@ -298,8 +298,12 @@
 	char *str;
 
 	g_return_if_fail(data != NULL);
 
+	/* save state */
+	if (settings_get_bool("session_save_on_quit"))
+		session_sigterm();
+
 	quitmsg = *data != '\0' ? data :
 		settings_get_str("quit_message");
 
 	/* disconnect from every server */
diff -r -U4 irssi-0.8.13/src/core/core.c irssi-0.8.13+autosession/src/core/core.c
--- irssi-0.8.13/src/core/core.c	2009-03-31 22:02:51.000000000 +0100
+++ irssi-0.8.13+autosession/src/core/core.c	2009-07-05 11:31:27.000000000 +0100
@@ -84,13 +84,13 @@
 static void read_settings(void)
 {
 #ifndef WIN32
 	static int signals[] = {
-		SIGINT, SIGQUIT, SIGTERM,
+		SIGINT, SIGQUIT,
 		SIGALRM, SIGUSR1, SIGUSR2
 	};
 	static char *signames[] = {
-		"int", "quit", "term",
+		"int", "quit",
 		"alrm", "usr1", "usr2"
 	};
 
 	const char *ignores;
diff -r -U4 irssi-0.8.13/src/core/servers-reconnect.c irssi-0.8.13+autosession/src/core/servers-reconnect.c
--- irssi-0.8.13/src/core/servers-reconnect.c	2009-03-31 22:02:51.000000000 +0100
+++ irssi-0.8.13+autosession/src/core/servers-reconnect.c	2009-07-05 10:30:48.000000000 +0100
@@ -140,9 +140,9 @@
 	conn->address = g_strdup(rec->address);
 	if (conn->port == 0) conn->port = rec->port;
 
 	server_setup_fill_reconn(conn, rec);
-	server_reconnect_add(conn, rec->last_connect+reconnect_time);
+	server_reconnect_add(conn, rec->last_connect == 0 ? 0 : rec->last_connect+reconnect_time);
 	server_connect_unref(conn);
 }
 
 static SERVER_CONNECT_REC *
@@ -242,8 +242,13 @@
 			time(NULL) : server->connect_time;
 		sserver->last_failed = !server->connected;
 		sserver->banned = server->banned;
                 sserver->dns_error = server->dns_error;
+
+		if (server->session_reconnect) {
+			sserver->last_connect = 0;
+			server->session_reconnect = 0;
+		}
 	}
 
 	if (sserver == NULL || conn->chatnet == NULL) {
 		/* not in any chatnet, just reconnect back to same server */
@@ -251,10 +256,10 @@
 		conn->address = g_strdup(server->connrec->address);
 		conn->port = server->connrec->port;
 		conn->password = g_strdup(server->connrec->password);
 
-		server_reconnect_add(conn, (server->connect_time == 0 ? time(NULL) :
-					    server->connect_time) + reconnect_time);
+		server_reconnect_add(conn, server->session_reconnect ? 0 : ((server->connect_time == 0 ? time(NULL) :
+					    server->connect_time) + reconnect_time));
 		server_connect_unref(conn);
 		return;
 	}
 
diff -r -U4 irssi-0.8.13/src/core/session.c irssi-0.8.13+autosession/src/core/session.c
--- irssi-0.8.13/src/core/session.c	2009-03-31 22:02:51.000000000 +0100
+++ irssi-0.8.13+autosession/src/core/session.c	2009-07-05 12:23:36.000000000 +0100
@@ -17,15 +17,19 @@
     with this program; if not, write to the Free Software Foundation, Inc.,
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
+#include <sys/types.h>
+#include <sys/socket.h>
+
 #include "module.h"
 #include "signals.h"
 #include "commands.h"
 #include "args.h"
 #include "net-sendbuffer.h"
 #include "pidwait.h"
 #include "lib-config/iconfig.h"
+#include "settings.h"
 
 #include "chat-protocols.h"
 #include "servers.h"
 #include "servers-setup.h"
@@ -33,8 +37,10 @@
 #include "nicklist.h"
 
 static char *session_file;
 char *irssi_binary = NULL;
+int nohandles = 0;
+int sigterm = 0;
 
 static char **session_args;
 
 void session_set_binary(const char *path)
@@ -53,8 +59,33 @@
 	fprintf(stderr, "exec failed: %s: %s\n",
 		session_args[0], g_strerror(errno));
 }
 
+void session_sigterm(void)
+{
+	CONFIG_REC *session;
+	char *session_file;
+
+	if (sigterm)
+		return;
+
+	sigterm = 1;
+
+	/* save the session */
+	session_file = g_strdup_printf("%s/sigterm_session", get_irssi_dir());
+	session = config_open(session_file, 0600);
+	unlink(session_file);
+
+	if (session) {
+		signal_emit("session save", 1, session);
+		config_write(session, NULL, -1);
+		config_close(session);
+	}
+
+	g_free(session_file);
+	session_file = NULL;
+}
+
 /* SYNTAX: UPGRADE [<irssi binary path>] */
 static void cmd_upgrade(const char *data)
 {
 	CONFIG_REC *session;
@@ -71,22 +102,27 @@
         session_file = g_strdup_printf("%s/session", get_irssi_dir());
 	session = config_open(session_file, 0600);
         unlink(session_file);
 
-	signal_emit("session save", 1, session);
-        config_write(session, NULL, -1);
-        config_close(session);
+	if (session) {
+		signal_emit("session save", 1, session);
+	        config_write(session, NULL, -1);
+	        config_close(session);
 
-	/* data may contain some other program as well, like
+		/* data may contain some other program as well, like
 	   /UPGRADE /usr/bin/screen irssi */
-	str = g_strdup_printf("%s --noconnect --session=%s --home=%s --config=%s",
+		str = g_strdup_printf("%s --noconnect --session=%s --home=%s --config=%s",
 			      binary, session_file, get_irssi_dir(), get_irssi_config());
-	g_free(binary);
-	g_free(session_file);
-        session_args = g_strsplit(str, " ", -1);
-        g_free(str);
-
-	signal_emit("gui exit", 0);
+		g_free(binary);
+		g_free(session_file);
+        	session_args = g_strsplit(str, " ", -1);
+	        g_free(str);
+
+		signal_emit("gui exit", 0);
+	} else {
+		g_free(session_file);
+		session_file = NULL;
+	}
 }
 
 static void session_save_nick(CHANNEL_REC *channel, NICK_REC *nick,
 			      CONFIG_REC *config, CONFIG_NODE *node)
@@ -164,13 +200,19 @@
 	config_node_set_bool(config, node, "ssl_verify", server->connrec->ssl_verify);
 	config_node_set_str(config, node, "ssl_cafile", server->connrec->ssl_cafile);
 	config_node_set_str(config, node, "ssl_capath", server->connrec->ssl_capath);
 
-	handle = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle));
+	if (sigterm)
+		handle = -1;
+	else
+		handle = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle));
 	config_node_set_int(config, node, "handle", handle);
 
 	signal_emit("session save server", 3, server, config, node);
 
+	if (sigterm)
+		return;
+
 	/* fake the server disconnection */
 	g_io_channel_unref(net_sendbuffer_handle(server->handle));
 	net_sendbuffer_destroy(server->handle, FALSE);
 	server->handle = NULL;
@@ -243,24 +285,30 @@
 	port = config_node_get_int(node, "port", 0);
 	chatnet = config_node_get_str(node, "chatnet", NULL);
 	password = config_node_get_str(node, "password", NULL);
 	nick = config_node_get_str(node, "nick", NULL);
-	handle = config_node_get_int(node, "handle", -1);
+	if (nohandles)
+		handle = -1;
+	else
+		handle = config_node_get_int(node, "handle", -1);
 
-	if (chat_type == NULL || address == NULL || nick == NULL || handle < 0)
+	if (chat_type == NULL || address == NULL || nick == NULL || handle < -1)
 		return;
 
 	proto = chat_protocol_find(chat_type);
 	if (proto == NULL || proto->not_initialized) {
-		if (handle < 0) close(handle);
+		if (handle >= 0) close(handle);
 		return;
 	}
 
 	conn = server_create_conn(proto->id, address, port,
 				  chatnet, password, nick);
 	if (conn != NULL) {
 		conn->reconnection = TRUE;
-		conn->connect_handle = g_io_channel_unix_new(handle);
+		if (handle >= 0)
+			conn->connect_handle = g_io_channel_unix_new(handle);
+		else
+			conn->connect_handle = g_io_channel_unix_new(socket(AF_LOCAL, SOCK_STREAM, 0));
 
 		server = proto->server_init_connect(conn);
 		server->version = g_strdup(config_node_get_str(node, "version", NULL));
 		server->session_reconnect = TRUE;
@@ -272,15 +320,22 @@
 
 static void sig_session_save(CONFIG_REC *config)
 {
 	CONFIG_NODE *node;
-	GSList *tmp;
+	GSList *tmp, *next;
         GString *str;
 
         /* save servers */
 	node = config_node_traverse(config, "(servers", TRUE);
-	while (servers != NULL)
-		session_save_server(servers->data, config, node);
+	if (!sigterm) {
+		while (servers != NULL)
+			session_save_server(servers->data, config, node);
+	} else {
+		for (tmp = servers; tmp != NULL; tmp = next) {
+			next = tmp->next;
+			session_save_server(tmp->data, config, node);
+		}
+	}
 
 	/* save pids */
         str = g_string_new(NULL);
 	for (tmp = pidwait_get_pids(); tmp != NULL; tmp = tmp->next)
@@ -313,20 +368,30 @@
 static void sig_init_finished(void)
 {
 	CONFIG_REC *session;
 
-	if (session_file == NULL)
-		return;
+	if (session_file == NULL) {
+		nohandles = 1;
+        session_file = g_strdup_printf("%s/sigterm_session", get_irssi_dir());
+	}
 
 	session = config_open(session_file, -1);
-	if (session == NULL)
+	if (session == NULL) {
+		unlink(session_file);
 		return;
+	}
 
 	config_parse(session);
         signal_emit("session restore", 1, session);
 	config_close(session);
 
 	unlink(session_file);
+
+	g_free(session_file);
+	session_file = NULL;
+
+	if (nohandles)
+		signal_emit("irssi init noconnect", 0);
 }
 
 void session_register_options(void)
 {
@@ -342,8 +407,11 @@
 void session_init(void)
 {
 	command_bind("upgrade", NULL, (SIGNAL_FUNC) cmd_upgrade);
 
+	settings_add_bool("misc", "session_save_on_sigterm", TRUE);
+	settings_add_bool("misc", "session_save_on_quit", TRUE);
+
 	signal_add("session save", (SIGNAL_FUNC) sig_session_save);
 	signal_add("session restore", (SIGNAL_FUNC) sig_session_restore);
 	signal_add("session save server", (SIGNAL_FUNC) session_save_server_channels);
 	signal_add("session restore server", (SIGNAL_FUNC) session_restore_server_channels);
diff -r -U4 irssi-0.8.13/src/core/session.h irssi-0.8.13+autosession/src/core/session.h
--- irssi-0.8.13/src/core/session.h	2009-03-31 22:02:51.000000000 +0100
+++ irssi-0.8.13+autosession/src/core/session.h	2009-07-05 11:19:46.000000000 +0100
@@ -4,8 +4,9 @@
 extern char *irssi_binary;
 
 void session_set_binary(const char *path);
 void session_upgrade(void);
+void session_sigterm(void);
 
 void session_register_options(void);
 void session_init(void);
 void session_deinit(void);
diff -r -U4 irssi-0.8.13/src/core/settings.c irssi-0.8.13+autosession/src/core/settings.c
--- irssi-0.8.13/src/core/settings.c	2009-03-31 22:02:51.000000000 +0100
+++ irssi-0.8.13+autosession/src/core/settings.c	2009-07-05 11:44:49.000000000 +0100
@@ -27,8 +27,9 @@
 #include "lib-config/iconfig.h"
 #include "recode.h"
 #include "settings.h"
 #include "default-config.h"
+#include "session.h"
 
 #include <signal.h>
 
 #define SETTINGS_AUTOSAVE_TIMEOUT (1000*60*60) /* 1 hour */
@@ -574,8 +575,12 @@
 {
 	/* if we get SIGTERM after this, just die instead of coming back here. */
 	signal(SIGTERM, SIG_DFL);
 
+	/* save state */
+	if (settings_get_bool("session_save_on_sigterm"))
+		session_sigterm();
+
 	/* quit from all servers too.. */
 	signal_emit("command quit", 1, "");
 
 	/* and die */
diff -r -U4 irssi-0.8.13/src/fe-common/core/fe-common-core.c irssi-0.8.13+autosession/src/fe-common/core/fe-common-core.c
--- irssi-0.8.13/src/fe-common/core/fe-common-core.c	2009-03-31 22:02:52.000000000 +0100
+++ irssi-0.8.13+autosession/src/fe-common/core/fe-common-core.c	2009-07-05 12:22:51.000000000 +0100
@@ -92,8 +92,13 @@
 void window_commands_deinit(void);
 
 static void sig_setup_changed(void);
 
+static void sig_noconnect(void)
+{
+	no_autoconnect = TRUE;
+}
+
 static void sig_connected(SERVER_REC *server)
 {
 	MODULE_DATA_SET(server, g_new0(MODULE_SERVER_REC, 1));
 }
@@ -194,8 +199,9 @@
 	fe_recode_init();
 
 	settings_check();
 
+        signal_add_first("irssi init noconnect", (SIGNAL_FUNC) sig_noconnect);
         signal_add_first("server connected", (SIGNAL_FUNC) sig_connected);
         signal_add_last("server disconnected", (SIGNAL_FUNC) sig_disconnected);
         signal_add_first("channel created", (SIGNAL_FUNC) sig_channel_created);
         signal_add_last("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed);
@@ -237,8 +243,9 @@
 
         theme_unregister();
 	themes_deinit();
 
+        signal_remove("irssi init noconnect", (SIGNAL_FUNC) sig_noconnect);
         signal_remove("setup changed", (SIGNAL_FUNC) sig_setup_changed);
         signal_remove("server connected", (SIGNAL_FUNC) sig_connected);
         signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
         signal_remove("channel created", (SIGNAL_FUNC) sig_channel_created);
@@ -460,8 +467,12 @@
 	if (setup_changed)
                 signal_emit("setup changed", 0);
 
         autorun_startup();
+}
+
+void fe_common_core_autoconnect(void)
+{
 	autoconnect_servers();
 }
 
 gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest)
diff -r -U4 irssi-0.8.13/src/fe-common/core/fe-common-core.h irssi-0.8.13+autosession/src/fe-common/core/fe-common-core.h
--- irssi-0.8.13/src/fe-common/core/fe-common-core.h	2009-03-31 22:02:52.000000000 +0100
+++ irssi-0.8.13+autosession/src/fe-common/core/fe-common-core.h	2009-07-05 12:22:59.000000000 +0100
@@ -4,8 +4,9 @@
 void fe_common_core_register_options(void);
 void fe_common_core_init(void);
 void fe_common_core_deinit(void);
 void fe_common_core_finish_init(void);
+void fe_common_core_autoconnect(void);
 
 /* Returns TRUE if "dest->target" or "dest->server_tag/dest->target" is found in
  * array, otherwise FALSE. */
 gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest);
diff -r -U4 irssi-0.8.13/src/fe-text/irssi.c irssi-0.8.13+autosession/src/fe-text/irssi.c
--- irssi-0.8.13/src/fe-text/irssi.c	2009-03-31 22:02:51.000000000 +0100
+++ irssi-0.8.13+autosession/src/fe-text/irssi.c	2009-07-05 12:23:20.000000000 +0100
@@ -192,8 +192,9 @@
 	dirty_check();
 
 	fe_common_core_finish_init();
 	signal_emit("irssi init finished", 0);
+	fe_common_core_autoconnect();
 
 	if (display_firsttimer) {
 		printtext_window(active_win, MSGLEVEL_CLIENTNOTICE,
 				 "%s", firsttimer_text);
