mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
Irssi won't automatically overwrite configuration files if they're
changed while irssi is running: - /SAVE asks whether to save it or not - autosave at quit saves it to config.autosave file git-svn-id: http://svn.irssi.org/repos/irssi/trunk@762 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
228c1d7f36
commit
a2cac63e56
@ -35,6 +35,10 @@ static GHashTable *settings;
|
|||||||
static char *last_error_msg;
|
static char *last_error_msg;
|
||||||
static int timeout_tag;
|
static int timeout_tag;
|
||||||
|
|
||||||
|
static time_t config_last_mtime;
|
||||||
|
static long config_last_size;
|
||||||
|
static unsigned int config_last_checksum;
|
||||||
|
|
||||||
static const char *settings_get_default_str(const char *key)
|
static const char *settings_get_default_str(const char *key)
|
||||||
{
|
{
|
||||||
SETTINGS_REC *rec;
|
SETTINGS_REC *rec;
|
||||||
@ -212,6 +216,51 @@ void sig_term(int n)
|
|||||||
raise(SIGTERM);
|
raise(SIGTERM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Yes, this is my own stupid checksum generator, some "real" algorithm
|
||||||
|
would be nice but would just take more space without much real benefit */
|
||||||
|
static unsigned int file_checksum(const char *fname)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
int n = 0;
|
||||||
|
unsigned int checksum = 0;
|
||||||
|
|
||||||
|
f = fopen(fname, "rb");
|
||||||
|
while (!feof(f))
|
||||||
|
checksum += fgetc(f) << ((n++ & 3)*8);
|
||||||
|
fclose(f);
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void irssi_config_save_state(const char *fname)
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
|
g_return_if_fail(fname != NULL);
|
||||||
|
|
||||||
|
if (stat(fname, &statbuf) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* save modify time, file size and checksum */
|
||||||
|
config_last_mtime = statbuf.st_mtime;
|
||||||
|
config_last_size = statbuf.st_size;
|
||||||
|
config_last_checksum = file_checksum(fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
int irssi_config_is_changed(const char *fname)
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
|
if (fname == NULL)
|
||||||
|
fname = mainconfig->fname;
|
||||||
|
|
||||||
|
if (stat(fname, &statbuf) != 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return config_last_mtime != statbuf.st_mtime &&
|
||||||
|
(config_last_size != statbuf.st_size ||
|
||||||
|
config_last_checksum != file_checksum(fname));
|
||||||
|
}
|
||||||
|
|
||||||
static CONFIG_REC *parse_configfile(const char *fname)
|
static CONFIG_REC *parse_configfile(const char *fname)
|
||||||
{
|
{
|
||||||
CONFIG_REC *config;
|
CONFIG_REC *config;
|
||||||
@ -239,6 +288,7 @@ static CONFIG_REC *parse_configfile(const char *fname)
|
|||||||
config_change_file_name(config, real_fname, 0660);
|
config_change_file_name(config, real_fname, 0660);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irssi_config_save_state(real_fname);
|
||||||
g_free(real_fname);
|
g_free(real_fname);
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
@ -323,22 +373,44 @@ int settings_reread(const char *fname)
|
|||||||
int settings_save(const char *fname)
|
int settings_save(const char *fname)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
|
int error;
|
||||||
|
|
||||||
if (config_write(mainconfig, fname, 0660) == 0)
|
if (fname == NULL)
|
||||||
return TRUE;
|
fname = mainconfig->fname;
|
||||||
|
|
||||||
/* error */
|
error = config_write(mainconfig, fname, 0660) != 0;
|
||||||
str = g_strdup_printf(_("Couldn't save configuration file: %s"),
|
irssi_config_save_state(fname);
|
||||||
config_last_error(mainconfig));
|
if (error) {
|
||||||
signal_emit("gui dialog", 2, "error", str);
|
str = g_strdup_printf(_("Couldn't save "
|
||||||
g_free(str);
|
"configuration file: %s"),
|
||||||
return FALSE;
|
config_last_error(mainconfig));
|
||||||
|
signal_emit("gui dialog", 2, "error", str);
|
||||||
|
g_free(str);
|
||||||
|
}
|
||||||
|
return !error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_autosave(void)
|
static void sig_autosave(void)
|
||||||
{
|
{
|
||||||
if (settings_get_bool("settings_autosave"))
|
char *fname, *str;
|
||||||
settings_save(NULL);
|
|
||||||
|
if (!settings_get_bool("settings_autosave"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!irssi_config_is_changed(NULL))
|
||||||
|
settings_save(NULL);
|
||||||
|
else {
|
||||||
|
fname = g_strconcat(mainconfig->fname, ".autosave", NULL);
|
||||||
|
str = g_strdup_printf(_("Configuration file was modified "
|
||||||
|
"while irssi was running. Saving "
|
||||||
|
"configuration to file '%s' instead"),
|
||||||
|
fname);
|
||||||
|
signal_emit("gui dialog", 2, "warning", str);
|
||||||
|
g_free(str);
|
||||||
|
|
||||||
|
settings_save(fname);
|
||||||
|
g_free(fname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void settings_init(void)
|
void settings_init(void)
|
||||||
@ -346,6 +418,7 @@ void settings_init(void)
|
|||||||
settings = g_hash_table_new((GHashFunc) g_str_hash,
|
settings = g_hash_table_new((GHashFunc) g_str_hash,
|
||||||
(GCompareFunc) g_str_equal);
|
(GCompareFunc) g_str_equal);
|
||||||
|
|
||||||
|
config_last_mtime = 0;
|
||||||
init_configfile();
|
init_configfile();
|
||||||
|
|
||||||
settings_add_bool("misc", "settings_autosave", TRUE);
|
settings_add_bool("misc", "settings_autosave", TRUE);
|
||||||
|
@ -57,6 +57,7 @@ SETTINGS_REC *settings_get_record(const char *key);
|
|||||||
/* 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 settings_save(const char *fname);
|
||||||
|
int irssi_config_is_changed(const char *fname);
|
||||||
|
|
||||||
void settings_init(void);
|
void settings_init(void);
|
||||||
void settings_deinit(void);
|
void settings_deinit(void);
|
||||||
|
@ -245,14 +245,38 @@ static void cmd_reload(const char *data)
|
|||||||
g_free(fname);
|
g_free(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void settings_save_fe(const char *fname)
|
||||||
|
{
|
||||||
|
if (settings_save(fname)) {
|
||||||
|
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
|
||||||
|
IRCTXT_CONFIG_SAVED, fname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void settings_save_confirm(const char *line, char *fname)
|
||||||
|
{
|
||||||
|
if (toupper(*line) == 'Y')
|
||||||
|
settings_save_fe(fname);
|
||||||
|
g_free(fname);
|
||||||
|
}
|
||||||
|
|
||||||
/* SYNTAX: SAVE [<file>] */
|
/* SYNTAX: SAVE [<file>] */
|
||||||
static void cmd_save(const char *data)
|
static void cmd_save(const char *data)
|
||||||
{
|
{
|
||||||
if (settings_save(*data != '\0' ? data : NULL)) {
|
if (*data == '\0')
|
||||||
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
|
data = mainconfig->fname;
|
||||||
IRCTXT_CONFIG_SAVED, *data != '\0' ? data :
|
|
||||||
mainconfig->fname);
|
if (!irssi_config_is_changed(data)) {
|
||||||
|
settings_save_fe(data);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
|
||||||
|
IRCTXT_CONFIG_MODIFIED, data);
|
||||||
|
signal_emit("gui entry redirect", 4,
|
||||||
|
settings_save_confirm,
|
||||||
|
_("Overwrite config (y/N)?"),
|
||||||
|
GINT_TO_POINTER(FALSE), g_strdup(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void fe_settings_init(void)
|
void fe_settings_init(void)
|
||||||
|
@ -202,6 +202,7 @@ FORMAT_REC fecommon_core_formats[] = {
|
|||||||
{ "bind_unknown_id", "Unknown bind action: $0", 1, { 0 } },
|
{ "bind_unknown_id", "Unknown bind action: $0", 1, { 0 } },
|
||||||
{ "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 } },
|
||||||
|
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
@ -167,7 +167,8 @@ enum {
|
|||||||
IRCTXT_BIND_KEY,
|
IRCTXT_BIND_KEY,
|
||||||
IRCTXT_BIND_UNKNOWN_ID,
|
IRCTXT_BIND_UNKNOWN_ID,
|
||||||
IRCTXT_CONFIG_SAVED,
|
IRCTXT_CONFIG_SAVED,
|
||||||
IRCTXT_CONFIG_RELOADED
|
IRCTXT_CONFIG_RELOADED,
|
||||||
|
IRCTXT_CONFIG_MODIFIED
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FORMAT_REC fecommon_core_formats[];
|
extern FORMAT_REC fecommon_core_formats[];
|
||||||
|
Loading…
Reference in New Issue
Block a user