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 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)
|
||||
{
|
||||
SETTINGS_REC *rec;
|
||||
@ -212,6 +216,51 @@ void sig_term(int n)
|
||||
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)
|
||||
{
|
||||
CONFIG_REC *config;
|
||||
@ -239,6 +288,7 @@ static CONFIG_REC *parse_configfile(const char *fname)
|
||||
config_change_file_name(config, real_fname, 0660);
|
||||
}
|
||||
|
||||
irssi_config_save_state(real_fname);
|
||||
g_free(real_fname);
|
||||
return config;
|
||||
}
|
||||
@ -323,22 +373,44 @@ int settings_reread(const char *fname)
|
||||
int settings_save(const char *fname)
|
||||
{
|
||||
char *str;
|
||||
int error;
|
||||
|
||||
if (config_write(mainconfig, fname, 0660) == 0)
|
||||
return TRUE;
|
||||
if (fname == NULL)
|
||||
fname = mainconfig->fname;
|
||||
|
||||
/* error */
|
||||
str = g_strdup_printf(_("Couldn't save configuration file: %s"),
|
||||
config_last_error(mainconfig));
|
||||
signal_emit("gui dialog", 2, "error", str);
|
||||
g_free(str);
|
||||
return FALSE;
|
||||
error = config_write(mainconfig, fname, 0660) != 0;
|
||||
irssi_config_save_state(fname);
|
||||
if (error) {
|
||||
str = g_strdup_printf(_("Couldn't save "
|
||||
"configuration file: %s"),
|
||||
config_last_error(mainconfig));
|
||||
signal_emit("gui dialog", 2, "error", str);
|
||||
g_free(str);
|
||||
}
|
||||
return !error;
|
||||
}
|
||||
|
||||
static void sig_autosave(void)
|
||||
{
|
||||
if (settings_get_bool("settings_autosave"))
|
||||
settings_save(NULL);
|
||||
char *fname, *str;
|
||||
|
||||
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)
|
||||
@ -346,6 +418,7 @@ void settings_init(void)
|
||||
settings = g_hash_table_new((GHashFunc) g_str_hash,
|
||||
(GCompareFunc) g_str_equal);
|
||||
|
||||
config_last_mtime = 0;
|
||||
init_configfile();
|
||||
|
||||
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 */
|
||||
int settings_reread(const char *fname);
|
||||
int settings_save(const char *fname);
|
||||
int irssi_config_is_changed(const char *fname);
|
||||
|
||||
void settings_init(void);
|
||||
void settings_deinit(void);
|
||||
|
@ -245,14 +245,38 @@ static void cmd_reload(const char *data)
|
||||
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>] */
|
||||
static void cmd_save(const char *data)
|
||||
{
|
||||
if (settings_save(*data != '\0' ? data : NULL)) {
|
||||
printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
|
||||
IRCTXT_CONFIG_SAVED, *data != '\0' ? data :
|
||||
mainconfig->fname);
|
||||
if (*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)
|
||||
|
@ -202,6 +202,7 @@ FORMAT_REC fecommon_core_formats[] = {
|
||||
{ "bind_unknown_id", "Unknown bind action: $0", 1, { 0 } },
|
||||
{ "config_saved", "Saved configuration to file $0", 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 }
|
||||
};
|
||||
|
@ -167,7 +167,8 @@ enum {
|
||||
IRCTXT_BIND_KEY,
|
||||
IRCTXT_BIND_UNKNOWN_ID,
|
||||
IRCTXT_CONFIG_SAVED,
|
||||
IRCTXT_CONFIG_RELOADED
|
||||
IRCTXT_CONFIG_RELOADED,
|
||||
IRCTXT_CONFIG_MODIFIED
|
||||
};
|
||||
|
||||
extern FORMAT_REC fecommon_core_formats[];
|
||||
|
Loading…
Reference in New Issue
Block a user