mirror of
https://github.com/weechat/weechat.git
synced 2026-07-01 15:26:37 +02:00
core: add option "-quit" for command /upgrade (save session and quit without restarting WeeChat, for delayed restoration)
This commit is contained in:
+71
-38
@@ -4622,12 +4622,11 @@ COMMAND_CALLBACK(upgrade)
|
||||
char *ptr_binary;
|
||||
char *exec_args[7] = { NULL, "-a", "--dir", NULL, "--upgrade", NULL };
|
||||
struct stat stat_buf;
|
||||
int rc;
|
||||
int rc, quit;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) buffer;
|
||||
(void) argv;
|
||||
|
||||
/*
|
||||
* it is forbidden to upgrade while there are some background process
|
||||
@@ -4642,40 +4641,48 @@ COMMAND_CALLBACK(upgrade)
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
ptr_binary = NULL;
|
||||
quit = 0;
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
ptr_binary = string_expand_home (argv_eol[1]);
|
||||
if (ptr_binary)
|
||||
if (string_strcasecmp (argv[1], "-quit") == 0)
|
||||
quit = 1;
|
||||
else
|
||||
{
|
||||
/* check if weechat binary is here and executable by user */
|
||||
rc = stat (ptr_binary, &stat_buf);
|
||||
if ((rc != 0) || (!S_ISREG(stat_buf.st_mode)))
|
||||
ptr_binary = string_expand_home (argv_eol[1]);
|
||||
if (ptr_binary)
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sCan't upgrade: WeeChat binary \"%s\" "
|
||||
"does not exist"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
ptr_binary);
|
||||
free (ptr_binary);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
if ((!(stat_buf.st_mode & S_IXUSR)) && (!(stat_buf.st_mode & S_IXGRP))
|
||||
&& (!(stat_buf.st_mode & S_IXOTH)))
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sCan't upgrade: WeeChat binary \"%s\" "
|
||||
"does not have execute permissions"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
ptr_binary);
|
||||
free (ptr_binary);
|
||||
return WEECHAT_RC_OK;
|
||||
/* check if weechat binary is here and executable by user */
|
||||
rc = stat (ptr_binary, &stat_buf);
|
||||
if ((rc != 0) || (!S_ISREG(stat_buf.st_mode)))
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sCan't upgrade: WeeChat binary \"%s\" "
|
||||
"does not exist"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
ptr_binary);
|
||||
free (ptr_binary);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
if ((!(stat_buf.st_mode & S_IXUSR)) && (!(stat_buf.st_mode & S_IXGRP))
|
||||
&& (!(stat_buf.st_mode & S_IXOTH)))
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sCan't upgrade: WeeChat binary \"%s\" "
|
||||
"does not have execute permissions"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
ptr_binary);
|
||||
free (ptr_binary);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!ptr_binary && !quit)
|
||||
ptr_binary = strdup (weechat_argv0);
|
||||
|
||||
if (!ptr_binary)
|
||||
if (!ptr_binary && !quit)
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sNot enough memory"),
|
||||
@@ -4683,25 +4690,27 @@ COMMAND_CALLBACK(upgrade)
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
gui_chat_printf (NULL,
|
||||
_("Upgrading WeeChat with binary file: \"%s\"..."),
|
||||
ptr_binary);
|
||||
if (ptr_binary)
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("Upgrading WeeChat with binary file: \"%s\"..."),
|
||||
ptr_binary);
|
||||
}
|
||||
|
||||
/* send "upgrade" signal to plugins */
|
||||
hook_signal_send ("upgrade", WEECHAT_HOOK_SIGNAL_STRING, NULL);
|
||||
hook_signal_send ("upgrade", WEECHAT_HOOK_SIGNAL_STRING,
|
||||
(quit) ? "quit" : NULL);
|
||||
|
||||
if (!upgrade_weechat_save ())
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sError: unable to save session in file"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
|
||||
free (ptr_binary);
|
||||
if (ptr_binary)
|
||||
free (ptr_binary);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
exec_args[0] = ptr_binary;
|
||||
exec_args[3] = strdup (weechat_home);
|
||||
|
||||
weechat_quit = 1;
|
||||
weechat_upgrading = 1;
|
||||
|
||||
@@ -4713,6 +4722,14 @@ COMMAND_CALLBACK(upgrade)
|
||||
gui_main_end (1);
|
||||
log_close ();
|
||||
|
||||
if (quit)
|
||||
{
|
||||
exit (0);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
exec_args[0] = ptr_binary;
|
||||
exec_args[3] = strdup (weechat_home);
|
||||
execvp (exec_args[0], exec_args);
|
||||
|
||||
/* this code should not be reached if execvp is ok */
|
||||
@@ -6116,9 +6133,12 @@ command_init ()
|
||||
&command_unset, NULL);
|
||||
hook_command (NULL, "upgrade",
|
||||
N_("upgrade WeeChat without disconnecting from servers"),
|
||||
N_("[<path_to_binary>]"),
|
||||
N_("[<path_to_binary>|-quit]"),
|
||||
N_("path_to_binary: path to WeeChat binary (default is "
|
||||
"current binary)\n\n"
|
||||
"current binary)\n"
|
||||
" -quit: close *ALL* connections, save session "
|
||||
"and quit WeeChat, which makes possible a delayed "
|
||||
"restoration (see below)\n\n"
|
||||
"This command upgrades and reloads a running WeeChat "
|
||||
"session. The new WeeChat binary must have been compiled "
|
||||
"or installed with a package manager before running this "
|
||||
@@ -6133,7 +6153,20 @@ command_init ()
|
||||
" 2. unload all plugins (configuration files (*.conf) "
|
||||
"are written on disk)\n"
|
||||
" 3. save WeeChat configuration (weechat.conf)\n"
|
||||
" 4. execute new WeeChat binary and reload session."),
|
||||
" 4. execute new WeeChat binary and reload session.\n\n"
|
||||
"With option \"-quit\", the process is slightly "
|
||||
"different:\n"
|
||||
" 1. close *ALL* connections (irc, xfer, relay, ...)\n"
|
||||
" 2. save session into files (*.upgrade)\n"
|
||||
" 3. unload all plugins\n"
|
||||
" 4. save WeeChat configuration\n"
|
||||
" 5. quit WeeChat\n"
|
||||
"Then later you can restore session with command: "
|
||||
"weechat-curses --upgrade\n"
|
||||
"IMPORTANT: you must restore the session with exactly "
|
||||
"same configuration (files *.conf).\n"
|
||||
"It is possible to restore WeeChat session on another "
|
||||
"machine if you copy the content of directory \"~/.weechat\""),
|
||||
"%(filename)",
|
||||
&command_upgrade, NULL);
|
||||
hook_command (NULL, "uptime",
|
||||
|
||||
+22
-18
@@ -96,33 +96,37 @@ irc_signal_upgrade_cb (void *data, const char *signal, const char *type_data,
|
||||
void *signal_data)
|
||||
{
|
||||
struct t_irc_server *ptr_server;
|
||||
int disconnected;
|
||||
int quit, ssl_disconnected;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) signal;
|
||||
(void) type_data;
|
||||
(void) signal_data;
|
||||
|
||||
irc_signal_upgrade_received = 1;
|
||||
|
||||
/*
|
||||
* FIXME: it's not possible to upgrade with SSL servers connected (GnuTLS
|
||||
* lib can't reload data after upgrade), so we close connection for
|
||||
* all SSL servers currently connected
|
||||
*/
|
||||
disconnected = 0;
|
||||
quit = (signal_data && (strcmp (signal_data, "quit") == 0));
|
||||
ssl_disconnected = 0;
|
||||
|
||||
for (ptr_server = irc_servers; ptr_server;
|
||||
ptr_server = ptr_server->next_server)
|
||||
{
|
||||
if (ptr_server->is_connected && ptr_server->ssl_connected)
|
||||
/*
|
||||
* FIXME: it's not possible to upgrade with SSL servers connected (GnuTLS
|
||||
* lib can't reload data after upgrade), so we close connection for
|
||||
* all SSL servers currently connected
|
||||
*/
|
||||
if (ptr_server->is_connected && (ptr_server->ssl_connected || quit))
|
||||
{
|
||||
disconnected++;
|
||||
weechat_printf (ptr_server->buffer,
|
||||
_("%s%s: disconnecting from server because upgrade "
|
||||
"can't work for servers connected via SSL"),
|
||||
weechat_prefix ("error"),
|
||||
IRC_PLUGIN_NAME);
|
||||
if (!quit)
|
||||
{
|
||||
ssl_disconnected++;
|
||||
weechat_printf (ptr_server->buffer,
|
||||
_("%s%s: disconnecting from server because upgrade "
|
||||
"can't work for servers connected via SSL"),
|
||||
weechat_prefix ("error"),
|
||||
IRC_PLUGIN_NAME);
|
||||
}
|
||||
irc_server_disconnect (ptr_server, 0, 0);
|
||||
/*
|
||||
* schedule reconnection: WeeChat will reconnect to this server
|
||||
@@ -133,15 +137,15 @@ irc_signal_upgrade_cb (void *data, const char *signal, const char *type_data,
|
||||
ptr_server->reconnect_start = time (NULL) - ptr_server->reconnect_delay - 1;
|
||||
}
|
||||
}
|
||||
if (disconnected > 0)
|
||||
if (ssl_disconnected > 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
/* TRANSLATORS: "%s" after "%d" is "server" or "servers" */
|
||||
_("%s%s: disconnected from %d %s (SSL connection "
|
||||
"not supported with upgrade)"),
|
||||
weechat_prefix ("error"), IRC_PLUGIN_NAME,
|
||||
disconnected,
|
||||
NG_("server", "servers", disconnected));
|
||||
ssl_disconnected,
|
||||
NG_("server", "servers", ssl_disconnected));
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
+25
-20
@@ -84,7 +84,7 @@ relay_signal_upgrade_cb (void *data, const char *signal, const char *type_data,
|
||||
{
|
||||
struct t_relay_server *ptr_server;
|
||||
struct t_relay_client *ptr_client;
|
||||
int disconnected;
|
||||
int quit, ssl_disconnected;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
@@ -101,38 +101,43 @@ relay_signal_upgrade_cb (void *data, const char *signal, const char *type_data,
|
||||
relay_server_close_socket (ptr_server);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: it's not possible to upgrade with SSL clients connected (GnuTLS
|
||||
* lib can't reload data after upgrade), so we close connection for
|
||||
* all SSL clients currently connected
|
||||
*/
|
||||
disconnected = 0;
|
||||
quit = (signal_data && (strcmp (signal_data, "quit") == 0));
|
||||
ssl_disconnected = 0;
|
||||
|
||||
for (ptr_client = relay_clients; ptr_client;
|
||||
ptr_client = ptr_client->next_client)
|
||||
{
|
||||
if ((ptr_client->sock >= 0) && ptr_client->ssl)
|
||||
/*
|
||||
* FIXME: it's not possible to upgrade with SSL clients connected (GnuTLS
|
||||
* lib can't reload data after upgrade), so we close connection for
|
||||
* all SSL clients currently connected
|
||||
*/
|
||||
if ((ptr_client->sock >= 0) && (ptr_client->ssl || quit))
|
||||
{
|
||||
disconnected++;
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: disconnecting from client %s%s%s because "
|
||||
"upgrade can't work for clients connected via SSL"),
|
||||
weechat_prefix ("error"),
|
||||
RELAY_PLUGIN_NAME,
|
||||
RELAY_COLOR_CHAT_CLIENT,
|
||||
ptr_client->desc,
|
||||
RELAY_COLOR_CHAT);
|
||||
if (!quit)
|
||||
{
|
||||
ssl_disconnected++;
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: disconnecting from client %s%s%s because "
|
||||
"upgrade can't work for clients connected via SSL"),
|
||||
weechat_prefix ("error"),
|
||||
RELAY_PLUGIN_NAME,
|
||||
RELAY_COLOR_CHAT_CLIENT,
|
||||
ptr_client->desc,
|
||||
RELAY_COLOR_CHAT);
|
||||
}
|
||||
relay_client_set_status (ptr_client, RELAY_STATUS_DISCONNECTED);
|
||||
}
|
||||
}
|
||||
if (disconnected > 0)
|
||||
if (ssl_disconnected > 0)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
/* TRANSLATORS: "%s" after "%d" is "client" or "clients" */
|
||||
_("%s%s: disconnected from %d %s (SSL connection "
|
||||
"not supported with upgrade)"),
|
||||
weechat_prefix ("error"), RELAY_PLUGIN_NAME,
|
||||
disconnected,
|
||||
NG_("client", "clients", disconnected));
|
||||
ssl_disconnected,
|
||||
NG_("client", "clients", ssl_disconnected));
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
+36
-23
@@ -74,6 +74,9 @@ int xfer_count = 0; /* number of xfer */
|
||||
int xfer_signal_upgrade_received = 0; /* signal "upgrade" received ? */
|
||||
|
||||
|
||||
void xfer_disconnect_all ();
|
||||
|
||||
|
||||
/*
|
||||
* xfer_valid: check if a xfer pointer exists
|
||||
* return 1 if xfer exists
|
||||
@@ -111,10 +114,12 @@ xfer_signal_upgrade_cb (void *data, const char *signal, const char *type_data,
|
||||
(void) data;
|
||||
(void) signal;
|
||||
(void) type_data;
|
||||
(void) signal_data;
|
||||
|
||||
xfer_signal_upgrade_received = 1;
|
||||
|
||||
if (signal_data && (strcmp (signal_data, "quit") == 0))
|
||||
xfer_disconnect_all ();
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
@@ -340,6 +345,35 @@ xfer_close (struct t_xfer *xfer, enum t_xfer_status status)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_disconnect_all: disconnect all active xfer (with a socket)
|
||||
*/
|
||||
|
||||
void
|
||||
xfer_disconnect_all ()
|
||||
{
|
||||
struct t_xfer *ptr_xfer;
|
||||
|
||||
for (ptr_xfer = xfer_list; ptr_xfer; ptr_xfer = ptr_xfer->next_xfer)
|
||||
{
|
||||
if (ptr_xfer->sock >= 0)
|
||||
{
|
||||
if (ptr_xfer->status == XFER_STATUS_ACTIVE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: aborting active xfer: \"%s\" from %s"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME,
|
||||
ptr_xfer->filename, ptr_xfer->remote_nick);
|
||||
weechat_log_printf (_("%s%s: aborting active xfer: \"%s\" from %s"),
|
||||
"", XFER_PLUGIN_NAME,
|
||||
ptr_xfer->filename,
|
||||
ptr_xfer->remote_nick);
|
||||
}
|
||||
xfer_close (ptr_xfer, XFER_STATUS_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* xfer_port_in_use: return 1 if a port is in used
|
||||
* (by an active or connecting xfer)
|
||||
@@ -1486,8 +1520,6 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
int
|
||||
weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
{
|
||||
struct t_xfer *ptr_xfer;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) plugin;
|
||||
|
||||
@@ -1496,26 +1528,7 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
|
||||
if (xfer_signal_upgrade_received)
|
||||
xfer_upgrade_save ();
|
||||
else
|
||||
{
|
||||
for (ptr_xfer = xfer_list; ptr_xfer; ptr_xfer = ptr_xfer->next_xfer)
|
||||
{
|
||||
if (ptr_xfer->sock >= 0)
|
||||
{
|
||||
if (ptr_xfer->status == XFER_STATUS_ACTIVE)
|
||||
{
|
||||
weechat_printf (NULL,
|
||||
_("%s%s: aborting active xfer: \"%s\" from %s"),
|
||||
weechat_prefix ("error"), XFER_PLUGIN_NAME,
|
||||
ptr_xfer->filename, ptr_xfer->remote_nick);
|
||||
weechat_log_printf (_("%s%s: aborting active xfer: \"%s\" from %s"),
|
||||
"", XFER_PLUGIN_NAME,
|
||||
ptr_xfer->filename,
|
||||
ptr_xfer->remote_nick);
|
||||
}
|
||||
xfer_close (ptr_xfer, XFER_STATUS_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
xfer_disconnect_all ();
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user