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 +#include + #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 [] */ 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 #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);