mirror of
https://github.com/irssi/irssi.git
synced 2026-08-22 10:02:22 +02:00
Save backup config during /upgrade
If the user has modified their config within Irssi since the config was last saved and then runs /upgrade, then we want to save a backup config (in ~/.irssi/config.clientbackup), which is reloaded upon the upgrade being done.
This commit is contained in:
parent
be70fa5eb7
commit
9003a57c0a
8 changed files with 69 additions and 18 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
|
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
|
||||||
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */
|
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */
|
||||||
|
#define IRSSI_HOME_CONFIG_BACKUP "config.clientbackup" /* config file name for upgrades */
|
||||||
|
|
||||||
#define IRSSI_ABI_VERSION 10
|
#define IRSSI_ABI_VERSION 10
|
||||||
|
|
||||||
|
|
@ -68,6 +69,7 @@ int g_input_add_full(GIOChannel *source, int priority, int condition,
|
||||||
const char *get_irssi_dir(void);
|
const char *get_irssi_dir(void);
|
||||||
/* return full path for ~/.irssi/config */
|
/* return full path for ~/.irssi/config */
|
||||||
const char *get_irssi_config(void);
|
const char *get_irssi_config(void);
|
||||||
|
void set_irssi_config(char *);
|
||||||
|
|
||||||
/* max. size for %d */
|
/* max. size for %d */
|
||||||
#define MAX_INT_STRLEN ((sizeof(int) * CHAR_BIT + 2) / 3 + 1)
|
#define MAX_INT_STRLEN ((sizeof(int) * CHAR_BIT + 2) / 3 + 1)
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,11 @@ const char *get_irssi_config(void)
|
||||||
return irssi_config_file;
|
return irssi_config_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_irssi_config(char *path)
|
||||||
|
{
|
||||||
|
irssi_config_file = path;
|
||||||
|
}
|
||||||
|
|
||||||
static void sig_reload_config(int signo)
|
static void sig_reload_config(int signo)
|
||||||
{
|
{
|
||||||
reload_config = TRUE;
|
reload_config = TRUE;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "net-sendbuffer.h"
|
#include "net-sendbuffer.h"
|
||||||
#include "pidwait.h"
|
#include "pidwait.h"
|
||||||
#include "lib-config/iconfig.h"
|
#include "lib-config/iconfig.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
#include "chat-protocols.h"
|
#include "chat-protocols.h"
|
||||||
#include "servers.h"
|
#include "servers.h"
|
||||||
|
|
@ -58,8 +59,8 @@ void session_upgrade(void)
|
||||||
/* SYNTAX: UPGRADE [<irssi binary path>] */
|
/* SYNTAX: UPGRADE [<irssi binary path>] */
|
||||||
static void cmd_upgrade(const char *data)
|
static void cmd_upgrade(const char *data)
|
||||||
{
|
{
|
||||||
CONFIG_REC *session;
|
CONFIG_REC *session, *config;
|
||||||
char *session_file, *str;
|
char *session_file, *config_file, *str;
|
||||||
char *binary;
|
char *binary;
|
||||||
|
|
||||||
if (*data == '\0')
|
if (*data == '\0')
|
||||||
|
|
@ -77,12 +78,19 @@ static void cmd_upgrade(const char *data)
|
||||||
config_write(session, NULL, -1);
|
config_write(session, NULL, -1);
|
||||||
config_close(session);
|
config_close(session);
|
||||||
|
|
||||||
|
/* save the config */
|
||||||
|
config_file = g_strdup_printf("%s/"IRSSI_HOME_CONFIG_BACKUP, get_irssi_dir());
|
||||||
|
unlink(config_file);
|
||||||
|
|
||||||
|
signal_emit("command save", 1, config_file);
|
||||||
|
|
||||||
/* data may contain some other program as well, like
|
/* data may contain some other program as well, like
|
||||||
/UPGRADE /usr/bin/screen irssi */
|
/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());
|
binary, session_file, get_irssi_dir(), config_file);
|
||||||
g_free(binary);
|
g_free(binary);
|
||||||
g_free(session_file);
|
g_free(session_file);
|
||||||
|
g_free(config_file);
|
||||||
session_args = g_strsplit(str, " ", -1);
|
session_args = g_strsplit(str, " ", -1);
|
||||||
g_free(str);
|
g_free(str);
|
||||||
|
|
||||||
|
|
@ -315,20 +323,42 @@ static void sig_session_restore(CONFIG_REC *config)
|
||||||
|
|
||||||
static void sig_init_finished(void)
|
static void sig_init_finished(void)
|
||||||
{
|
{
|
||||||
CONFIG_REC *session;
|
CONFIG_REC *session, *config;
|
||||||
|
char *config_file;
|
||||||
if (session_file == NULL)
|
FILE *fp;
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (session_file != NULL) {
|
||||||
session = config_open(session_file, -1);
|
session = config_open(session_file, -1);
|
||||||
if (session == NULL)
|
if (session != NULL) {
|
||||||
return;
|
|
||||||
|
|
||||||
config_parse(session);
|
config_parse(session);
|
||||||
signal_emit("session restore", 1, session);
|
signal_emit("session restore", 1, session);
|
||||||
config_close(session);
|
config_close(session);
|
||||||
|
}
|
||||||
|
|
||||||
unlink(session_file);
|
unlink(session_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
config_file = g_strdup_printf("%s/"IRSSI_HOME_CONFIG_BACKUP, get_irssi_dir());
|
||||||
|
|
||||||
|
if ((fp = fopen(config_file, "r")) != NULL) {
|
||||||
|
/* load backup */
|
||||||
|
signal_emit("command reload", 1, config_file);
|
||||||
|
backupconfig = parse_configfile(config_file);
|
||||||
|
|
||||||
|
/* set irssi_config_file back to default so any future saves/reloads behave as expected */
|
||||||
|
set_irssi_config(g_strdup_printf("%s/"IRSSI_HOME_CONFIG, get_irssi_dir()));
|
||||||
|
/* load regular config into mainconfig */
|
||||||
|
signal_emit("command reload", 1, get_irssi_config());
|
||||||
|
|
||||||
|
/* setup mainconfig so that data from backup config is saved on next save */
|
||||||
|
mainconfig->mainnode = backupconfig->mainnode;
|
||||||
|
mainconfig->cache = backupconfig->cache;
|
||||||
|
mainconfig->cache_nodes = backupconfig->cache_nodes;
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(config_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_register_options(void)
|
void session_register_options(void)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
#define SETTINGS_AUTOSAVE_TIMEOUT (1000*60*60) /* 1 hour */
|
#define SETTINGS_AUTOSAVE_TIMEOUT (1000*60*60) /* 1 hour */
|
||||||
|
|
||||||
CONFIG_REC *mainconfig;
|
CONFIG_REC *mainconfig;
|
||||||
|
CONFIG_REC *backupconfig = NULL;
|
||||||
|
|
||||||
static GString *last_errors;
|
static GString *last_errors;
|
||||||
static GSList *last_invalid_modules;
|
static GSList *last_invalid_modules;
|
||||||
|
|
@ -673,7 +674,7 @@ static unsigned int file_checksum(const char *fname)
|
||||||
return checksum;
|
return checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void irssi_config_save_state(const char *fname)
|
void irssi_config_save_state(const char *fname)
|
||||||
{
|
{
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
|
|
@ -703,7 +704,7 @@ int irssi_config_is_changed(const char *fname)
|
||||||
config_last_checksum != file_checksum(fname));
|
config_last_checksum != file_checksum(fname));
|
||||||
}
|
}
|
||||||
|
|
||||||
static CONFIG_REC *parse_configfile(const char *fname)
|
CONFIG_REC *parse_configfile(const char *fname)
|
||||||
{
|
{
|
||||||
CONFIG_REC *config;
|
CONFIG_REC *config;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
@ -827,6 +828,9 @@ int settings_save(const char *fname, int autosave)
|
||||||
g_free(str);
|
g_free(str);
|
||||||
}
|
}
|
||||||
signal_emit("setup saved", 2, fname, GINT_TO_POINTER(autosave));
|
signal_emit("setup saved", 2, fname, GINT_TO_POINTER(autosave));
|
||||||
|
if (backupconfig != NULL && backupconfig->fname != NULL) {
|
||||||
|
unlink(backupconfig->fname);
|
||||||
|
}
|
||||||
return !error;
|
return !error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ typedef struct {
|
||||||
#define iconfig_node_add_list(a, b) config_node_add_list(mainconfig, a, b)
|
#define iconfig_node_add_list(a, b) config_node_add_list(mainconfig, a, b)
|
||||||
|
|
||||||
extern struct _CONFIG_REC *mainconfig;
|
extern struct _CONFIG_REC *mainconfig;
|
||||||
|
extern struct _CONFIG_REC *backupconfig;
|
||||||
extern const char *default_config;
|
extern const char *default_config;
|
||||||
|
|
||||||
/* Functions for handling the "settings" node of Irssi configuration */
|
/* Functions for handling the "settings" node of Irssi configuration */
|
||||||
|
|
@ -123,7 +124,9 @@ void settings_clean_invalid(void);
|
||||||
/* if `fname' is NULL, the default is used */
|
/* if `fname' is NULL, the default is used */
|
||||||
int settings_reread(const char *fname);
|
int settings_reread(const char *fname);
|
||||||
int settings_save(const char *fname, int autosave);
|
int settings_save(const char *fname, int autosave);
|
||||||
|
void irssi_config_save_state(const char *fname);
|
||||||
int irssi_config_is_changed(const char *fname);
|
int irssi_config_is_changed(const char *fname);
|
||||||
|
struct _CONFIG_REC *parse_configfile(const char *fname);
|
||||||
|
|
||||||
void settings_init(void);
|
void settings_init(void);
|
||||||
void settings_deinit(void);
|
void settings_deinit(void);
|
||||||
|
|
|
||||||
|
|
@ -364,9 +364,12 @@ static void cmd_save(const char *data)
|
||||||
if (*fname == '\0')
|
if (*fname == '\0')
|
||||||
fname = mainconfig->fname;
|
fname = mainconfig->fname;
|
||||||
|
|
||||||
if (!irssi_config_is_changed(fname))
|
if (irssi_config_is_changed(fname) && backupconfig != NULL) {
|
||||||
settings_save_fe(fname);
|
/* config file modified outside irssi and backup config exists */
|
||||||
else {
|
/* must not save and direct user to merge files outside of irssi */
|
||||||
|
printformat(NULL,NULL, MSGLEVEL_CLIENTNOTICE,
|
||||||
|
TXT_CONFIG_CONFLICT, fname, backupconfig->fname);
|
||||||
|
} else if (irssi_config_is_changed(fname)) {
|
||||||
/* config file modified outside irssi */
|
/* config file modified outside irssi */
|
||||||
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
|
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
|
||||||
TXT_CONFIG_MODIFIED, fname);
|
TXT_CONFIG_MODIFIED, fname);
|
||||||
|
|
@ -376,6 +379,8 @@ static void cmd_save(const char *data)
|
||||||
keyboard_entry_redirect((SIGNAL_FUNC) settings_save_confirm,
|
keyboard_entry_redirect((SIGNAL_FUNC) settings_save_confirm,
|
||||||
format, 0, g_strdup(fname));
|
format, 0, g_strdup(fname));
|
||||||
g_free(format);
|
g_free(format);
|
||||||
|
} else {
|
||||||
|
settings_save_fe(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_params_free(free_arg);
|
cmd_params_free(free_arg);
|
||||||
|
|
|
||||||
|
|
@ -279,6 +279,7 @@ FORMAT_REC fecommon_core_formats[] = {
|
||||||
{ "config_saved", "Saved configuration to file $0", 1, { 0 } },
|
{ "config_saved", "Saved configuration to file $0", 1, { 0 } },
|
||||||
{ "config_reloaded", "Reloaded configuration", 1, { 0 } },
|
{ "config_reloaded", "Reloaded configuration", 1, { 0 } },
|
||||||
{ "config_modified", "Configuration file was modified since irssi was last started - do you want to overwrite the possible changes?", 1, { 0 } },
|
{ "config_modified", "Configuration file was modified since irssi was last started - do you want to overwrite the possible changes?", 1, { 0 } },
|
||||||
|
{ "config_conflict", "Configuration file was modified since irssi was last started and backup config from upgrade exists - please use external merge tool to merge $0 and $1 into $0. Config was not saved.", 2, { 0, 0 } },
|
||||||
{ "glib_error", "{error $0} $1", 2, { 0, 0 } },
|
{ "glib_error", "{error $0} $1", 2, { 0, 0 } },
|
||||||
{ "overwrite_config", "Overwrite config (y/N)?", 0 },
|
{ "overwrite_config", "Overwrite config (y/N)?", 0 },
|
||||||
{ "set_title", "[{hilight $0}]", 1, { 0 } },
|
{ "set_title", "[{hilight $0}]", 1, { 0 } },
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ enum {
|
||||||
TXT_CONFIG_SAVED,
|
TXT_CONFIG_SAVED,
|
||||||
TXT_CONFIG_RELOADED,
|
TXT_CONFIG_RELOADED,
|
||||||
TXT_CONFIG_MODIFIED,
|
TXT_CONFIG_MODIFIED,
|
||||||
|
TXT_CONFIG_CONFLICT,
|
||||||
TXT_GLIB_ERROR,
|
TXT_GLIB_ERROR,
|
||||||
TXT_OVERWRITE_CONFIG,
|
TXT_OVERWRITE_CONFIG,
|
||||||
TXT_SET_TITLE,
|
TXT_SET_TITLE,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue