1
0
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:
Timo Sirainen 2000-10-15 19:21:21 +00:00 committed by cras
parent 228c1d7f36
commit a2cac63e56
5 changed files with 115 additions and 15 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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 }
};

View File

@ -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[];