Config file handling
Adam Byrtek / alpha
alpha at student.uci.agh.edu.pl
Thu Mar 20 22:55:58 UTC 2003
Patch to write config to temporary file and then 'atomicaly' move it
to proper place.
Moreover it is a fix for following nasty bug which happend when no
~/.mc/ini is found:
open("/usr/local/share/mc/mc.ini",
O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission
denied)
We should not try to write to public files, so profile_name should be
used only for reading... But dump_profile still wants to save file
(even unmodified), so we check and save only in home_dir.
Regards
Patch attached and in BTS
Adam
--
_.|._ |_ _. : Adam Byrtek /alpha/
(_|||_)| |(_| : email alpha@(irc.pl|debian.org)
| : jabber alpha.pl(at)jabber.org, pgp 0xB25952C0
-------------- next part --------------
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/mc/src/ChangeLog,v
retrieving revision 1.1145
diff -u -r1.1145 ChangeLog
--- ChangeLog 19 Mar 2003 13:39:48 -0000 1.1145
+++ ChangeLog 20 Mar 2003 22:54:26 -0000
@@ -1,0 +1,12 @@
+2003-03-20 Adam Byrtek <alpha at debian.org>
+
+ * profile.c (dump_profile): When saving config files, write to
+ a copy, then replace the file. Retain file mode.
+ * hotlist.c (save hotlist): Likewise.
+
+ * setup.c (dump_profile), setup.c (profile_name), hotlist.c
+ (profile_name), learn.c (profile_name), panelize.c
+ (profile_name): Avoid writing config files outside home
+ directory (happend when no .mc/ini existed). Use profile_name
+ only for reading.
+
Index: hotlist.c
===================================================================
RCS file: /cvs/gnome/mc/src/hotlist.c,v
retrieving revision 1.44
diff -u -r1.44 hotlist.c
--- hotlist.c 21 Dec 2002 08:43:15 -0000 1.44
+++ hotlist.c 20 Mar 2003 22:54:26 -0000
@@ -1328,23 +1328,26 @@
static void
clean_up_hotlist_groups (char *section)
{
- char *grp_section;
+ char *profile, *grp_section;
void *profile_keys;
char *key, *value;
+ profile = concat_dir_and_file (home_dir, PROFILE_NAME);
+
grp_section = g_strconcat (section, ".Group", NULL);
- if (profile_has_section (section, profile_name))
- profile_clean_section (section, profile_name);
- if (profile_has_section (grp_section, profile_name)) {
- profile_keys = profile_init_iterator (grp_section, profile_name);
+ if (profile_has_section (section, profile))
+ profile_clean_section (section, profile);
+ if (profile_has_section (grp_section, profile)) {
+ profile_keys = profile_init_iterator (grp_section, profile);
while (profile_keys) {
profile_keys = profile_iterator_next (profile_keys, &key, &value);
clean_up_hotlist_groups (key);
}
- profile_clean_section (grp_section, profile_name);
+ profile_clean_section (grp_section, profile);
}
g_free (grp_section);
+ g_free (profile);
}
@@ -1416,16 +1419,17 @@
save_group (struct hotlist *grp)
{
struct hotlist *current = grp->head;
- char *group_section;
+ char *group_section, *profile;
+ profile = concat_dir_and_file (home_dir, PROFILE_NAME);
group_section = find_group_section (grp);
- profile_clean_section (group_section, profile_name);
+ profile_clean_section (group_section, profile);
for (;current && current->type == HL_TYPE_GROUP; current = current->next){
WritePrivateProfileString (group_section,
current->directory,
current->label,
- profile_name);
+ profile);
}
g_free (group_section);
@@ -1434,13 +1438,14 @@
current = current->next)
save_group (current);
- profile_clean_section (grp->directory, profile_name);
+ profile_clean_section (grp->directory, profile);
for (;current; current = current->next){
WritePrivateProfileString (grp->directory,
current->directory,
current->label,
- profile_name);
+ profile);
}
+ g_free (profile);
}
static int list_level = 0;
@@ -1510,23 +1515,23 @@
struct stat stat_buf;
if (!hotlist_state.readonly && hotlist_state.modified && hotlist_file_name) {
- char *fbak = g_strconcat (hotlist_file_name, ".bak", NULL);
+ char *ftmp = g_strconcat (hotlist_file_name, ".tmp", NULL);
- rename (hotlist_file_name, fbak);
- if ((hotlist_file = fopen (hotlist_file_name, "w")) != 0) {
- if (stat (fbak, &stat_buf) == 0)
- chmod (hotlist_file_name, stat_buf.st_mode);
+ if ((hotlist_file = fopen (ftmp, "w")) != 0) {
+ if (stat (hotlist_file_name, &stat_buf) == 0)
+ chmod (ftmp, stat_buf.st_mode);
else
- chmod (hotlist_file_name, S_IRUSR | S_IWUSR);
+ chmod (ftmp, S_IRUSR | S_IWUSR);
hot_save_group (hotlist);
fclose (hotlist_file);
- stat (hotlist_file_name, &stat_buf);
- hotlist_file_mtime = stat_buf.st_mtime;
- saved = 1;
- hotlist_state.modified = 0;
- } else
- rename (fbak, hotlist_file_name);
- g_free (fbak);
+ if (rename (ftmp, hotlist_file_name) == 0) {
+ stat (hotlist_file_name, &stat_buf);
+ hotlist_file_mtime = stat_buf.st_mtime;
+ saved = 1;
+ hotlist_state.modified = 0;
+ }
+ }
+ g_free (ftmp);
}
return saved;
Index: learn.c
===================================================================
RCS file: /cvs/gnome/mc/src/learn.c,v
retrieving revision 1.19
diff -u -r1.19 learn.c
--- learn.c 21 Oct 2002 22:54:21 -0000 1.19
+++ learn.c 20 Mar 2003 22:54:26 -0000
@@ -310,12 +310,15 @@
int i;
int profile_changed = 0;
char *section = g_strconcat ("terminal:", getenv ("TERM"), NULL);
+ char *profile;
+ profile = concat_dir_and_file (home_dir, PROFILE_NAME);
+
for (i = 0; i < learn_total; i++) {
if (learnkeys [i].sequence != NULL) {
profile_changed = 1;
WritePrivateProfileString (section, key_name_conv_tab [i].name,
- learnkeys [i].sequence, profile_name);
+ learnkeys [i].sequence, profile);
}
}
@@ -329,6 +332,7 @@
sync_profiles ();
g_free (section);
+ g_free (profile);
}
void learn_keys (void)
Index: panelize.c
===================================================================
RCS file: /cvs/gnome/mc/src/panelize.c,v
retrieving revision 1.33
diff -u -r1.33 panelize.c
--- panelize.c 8 Dec 2002 04:16:30 -0000 1.33
+++ panelize.c 20 Mar 2003 22:54:26 -0000
@@ -327,16 +327,20 @@
void save_panelize (void)
{
struct panelize *current = panelize;
+ char *profile;
- profile_clean_section (panelize_section, profile_name);
+ profile = concat_dir_and_file (home_dir, PROFILE_NAME);
+
+ profile_clean_section (panelize_section, profile);
for (;current; current = current->next){
if (strcmp (current->label, _("Other command")))
WritePrivateProfileString (panelize_section,
current->label,
current->command,
- profile_name);
+ profile);
}
sync_profiles ();
+ g_free(profile);
}
void done_panelize (void)
Index: profile.c
===================================================================
RCS file: /cvs/gnome/mc/src/profile.c,v
retrieving revision 1.10
diff -u -r1.10 profile.c
--- profile.c 3 Mar 2003 07:59:11 -0000 1.10
+++ profile.c 20 Mar 2003 22:54:26 -0000
@@ -395,16 +395,32 @@
static void dump_profile (TProfile *p)
{
FILE *profile;
+ struct stat stat_buf;
+ char *tmpFileName;
if (!p)
return;
dump_profile (p->link);
/* .ado: p->FileName can be empty, it's better to jump over */
- if (p->FileName[0] != (char) 0)
- if ((profile = fopen (p->FileName, "w")) != NULL){
+ if (p->FileName[0] == (char) 0)
+ return;
+
+ /* write files in home dir only */
+ if (strncmp (p->FileName, home_dir, sizeof(home_dir)) != 0)
+ return;
+
+ /* save to temporary file, 'atomic' rename after completion */
+ tmpFileName = g_strconcat (p->FileName, ".tmp", NULL);
+
+ if ((profile = fopen (tmpFileName, "w")) != NULL){
+ if (stat (p->FileName, &stat_buf) == 0)
+ chmod (tmpFileName, stat_buf.st_mode);
+ else
+ chmod (tmpFileName, S_IRUSR | S_IWUSR);
dump_sections (profile, p->Section);
fclose (profile);
- }
+ rename (tmpFileName, p->FileName);
+ }
}
/*
@@ -510,7 +526,6 @@
/* We assume the user has called one of the other initialization funcs */
if (!find_loaded (file, §ion)){
- fprintf (stderr,"Warning: profile_clean_section called before init\n");
return;
}
/* We only disable the section, so it will still be freed, but it */
Index: setup.c
===================================================================
RCS file: /cvs/gnome/mc/src/setup.c,v
retrieving revision 1.73
diff -u -r1.73 setup.c
--- setup.c 23 Jan 2003 14:26:22 -0000 1.73
+++ setup.c 20 Mar 2003 22:54:26 -0000
@@ -219,38 +219,42 @@
void
panel_save_setup (struct WPanel *panel, char *section)
{
- char buffer [BUF_TINY];
+ char buffer [BUF_TINY], *profile;
int i;
+ profile = concat_dir_and_file (home_dir, PROFILE_NAME);
+
g_snprintf (buffer, sizeof (buffer), "%d", panel->reverse);
- save_string (section, "reverse", buffer, profile_name);
+ save_string (section, "reverse", buffer, profile);
g_snprintf (buffer, sizeof (buffer), "%d", panel->case_sensitive);
- save_string (section, "case_sensitive", buffer, profile_name);
+ save_string (section, "case_sensitive", buffer, profile);
for (i = 0; sort_names [i].key; i++)
if (sort_names [i].sort_type == (sortfn *) panel->sort_type){
save_string (section, "sort_order",
- sort_names [i].key, profile_name);
+ sort_names [i].key, profile);
break;
}
for (i = 0; list_types [i].key; i++)
if (list_types [i].list_type == panel->list_type){
- save_string (section, "list_mode", list_types [i].key, profile_name);
+ save_string (section, "list_mode", list_types [i].key, profile);
break;
}
save_string (section, "user_format",
- panel->user_format, profile_name);
+ panel->user_format, profile);
for (i = 0; i < LIST_TYPES; i++){
g_snprintf (buffer, sizeof (buffer), "user_status%d", i);
save_string (section, buffer,
- panel->user_status_format [i], profile_name);
+ panel->user_status_format [i], profile);
}
g_snprintf (buffer, sizeof (buffer), "%d", panel->user_mini_status);
save_string (section, "user_mini_status", buffer,
- profile_name);
+ profile);
+
+ g_free (profile);
}
void
@@ -290,13 +294,17 @@
panel_save_type (char *section, int type)
{
int i;
+ char *profile;
+
+ profile = concat_dir_and_file (home_dir, PROFILE_NAME);
for (i = 0; panel_types [i].opt_name; i++)
if (panel_types [i].opt_type == type){
save_string (section, "display", panel_types [i].opt_name,
- profile_name);
+ profile);
break;
}
+ g_free(profile);
}
void
@@ -347,7 +355,7 @@
#ifdef HAVE_CHARSET
save_string( "Misc", "display_codepage",
- get_codepage_id( display_codepage ), profile_name );
+ get_codepage_id( display_codepage ), profile );
#endif /* HAVE_CHARSET */
g_free (profile);
@@ -476,7 +484,7 @@
void
load_setup (void)
{
- char *profile;
+ char *profile, *profile_writable;
int i;
profile = setup_init ();
@@ -536,8 +544,10 @@
/* Load the directory history */
/* directory_history_load (); */
/* Remove the temporal entries */
- profile_clean_section ("Temporal:New Left Panel", profile_name);
- profile_clean_section ("Temporal:New Right Panel", profile_name);
+ profile_writable = concat_dir_and_file (home_dir, PROFILE_NAME);
+ profile_clean_section ("Temporal:New Left Panel", profile_writable);
+ profile_clean_section ("Temporal:New Right Panel", profile_writable);
+ g_free (profile_writable);
#if defined(USE_VFS) && defined (USE_NETCODE)
ftpfs_init_passwd ();
#endif /* USE_VFS && USE_NETCODE */
More information about the mc-devel
mailing list