root/lib/mcconfig/common.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. mc_config_new_or_override_file
  2. mc_config_init
  3. mc_config_deinit
  4. mc_config_has_param
  5. mc_config_has_group
  6. mc_config_del_key
  7. mc_config_del_group
  8. mc_config_read_file
  9. mc_config_save_file
  10. mc_config_save_to_file

   1 /*
   2    Configure module for the Midnight Commander
   3 
   4    Copyright (C) 1994-2024
   5    Free Software Foundation, Inc.
   6 
   7    This file is part of the Midnight Commander.
   8 
   9    The Midnight Commander is free software: you can redistribute it
  10    and/or modify it under the terms of the GNU General Public License as
  11    published by the Free Software Foundation, either version 3 of the License,
  12    or (at your option) any later version.
  13 
  14    The Midnight Commander is distributed in the hope that it will be useful,
  15    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17    GNU General Public License for more details.
  18 
  19    You should have received a copy of the GNU General Public License
  20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  21  */
  22 
  23 #include <config.h>
  24 
  25 #include <sys/types.h>
  26 #include <sys/stat.h>
  27 #include <unistd.h>
  28 #include <errno.h>              /* extern int errno */
  29 
  30 #include "lib/global.h"
  31 #include "lib/vfs/vfs.h"        /* mc_stat */
  32 #include "lib/util.h"
  33 
  34 #include "lib/mcconfig.h"
  35 
  36 /*** global variables ****************************************************************************/
  37 
  38 /*** file scope macro definitions ****************************************************************/
  39 
  40 /*** file scope type declarations ****************************************************************/
  41 
  42 /*** forward declarations (file scope functions) *************************************************/
  43 
  44 /*** file scope variables ************************************************************************/
  45 
  46 /* --------------------------------------------------------------------------------------------- */
  47 /*** file scope functions ************************************************************************/
  48 /* --------------------------------------------------------------------------------------------- */
  49 
  50 static gboolean
  51 mc_config_new_or_override_file (mc_config_t * mc_config, const gchar * ini_path, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
  52 {
  53     gchar *data, *written_data;
  54     gsize len, total_written;
  55     gboolean ret;
  56     int fd;
  57     ssize_t cur_written;
  58     vfs_path_t *ini_vpath;
  59 
  60     mc_return_val_if_error (mcerror, FALSE);
  61 
  62     data = g_key_file_to_data (mc_config->handle, &len, NULL);
  63     if (!exist_file (ini_path))
  64     {
  65         ret = g_file_set_contents (ini_path, data, len, mcerror);
  66         g_free (data);
  67         return ret;
  68     }
  69 
  70     mc_util_make_backup_if_possible (ini_path, "~");
  71 
  72     ini_vpath = vfs_path_from_str (ini_path);
  73     fd = mc_open (ini_vpath, O_WRONLY | O_TRUNC, 0);
  74     vfs_path_free (ini_vpath, TRUE);
  75 
  76     if (fd == -1)
  77     {
  78         mc_propagate_error (mcerror, 0, "%s", unix_error_string (errno));
  79         g_free (data);
  80         return FALSE;
  81     }
  82 
  83     for (written_data = data, total_written = len;
  84          (cur_written = mc_write (fd, (const void *) written_data, total_written)) > 0;
  85          written_data += cur_written, total_written -= cur_written)
  86         ;
  87 
  88     mc_close (fd);
  89     g_free (data);
  90 
  91     if (cur_written == -1)
  92     {
  93         mc_util_restore_from_backup_if_possible (ini_path, "~");
  94         mc_propagate_error (mcerror, 0, "%s", unix_error_string (errno));
  95         return FALSE;
  96     }
  97 
  98     mc_util_unlink_backup_if_possible (ini_path, "~");
  99     return TRUE;
 100 }
 101 
 102 /* --------------------------------------------------------------------------------------------- */
 103 /*** public functions ****************************************************************************/
 104 /* --------------------------------------------------------------------------------------------- */
 105 
 106 mc_config_t *
 107 mc_config_init (const gchar * ini_path, gboolean read_only)
     /* [previous][next][first][last][top][bottom][index][help]  */
 108 {
 109     mc_config_t *mc_config;
 110     struct stat st;
 111 
 112     mc_config = g_try_malloc0 (sizeof (mc_config_t));
 113     if (mc_config == NULL)
 114         return NULL;
 115 
 116     mc_config->handle = g_key_file_new ();
 117     if (mc_config->handle == NULL)
 118     {
 119         g_free (mc_config);
 120         return NULL;
 121     }
 122 
 123     if (ini_path == NULL)
 124         return mc_config;
 125 
 126     if (exist_file (ini_path))
 127     {
 128         vfs_path_t *vpath;
 129 
 130         vpath = vfs_path_from_str (ini_path);
 131         if (mc_stat (vpath, &st) == 0 && st.st_size != 0)
 132         {
 133             GKeyFileFlags flags = G_KEY_FILE_NONE;
 134 
 135             if (!read_only)
 136                 flags |= G_KEY_FILE_KEEP_COMMENTS;
 137 
 138             /* file exists and not empty */
 139             g_key_file_load_from_file (mc_config->handle, ini_path, flags, NULL);
 140         }
 141         vfs_path_free (vpath, TRUE);
 142     }
 143 
 144     mc_config->ini_path = g_strdup (ini_path);
 145     return mc_config;
 146 }
 147 
 148 /* --------------------------------------------------------------------------------------------- */
 149 
 150 void
 151 mc_config_deinit (mc_config_t * mc_config)
     /* [previous][next][first][last][top][bottom][index][help]  */
 152 {
 153     if (mc_config != NULL)
 154     {
 155         g_free (mc_config->ini_path);
 156         g_key_file_free (mc_config->handle);
 157         g_free (mc_config);
 158     }
 159 }
 160 
 161 /* --------------------------------------------------------------------------------------------- */
 162 
 163 gboolean
 164 mc_config_has_param (const mc_config_t * mc_config, const char *group, const gchar * param)
     /* [previous][next][first][last][top][bottom][index][help]  */
 165 {
 166     char *value;
 167     gboolean ret;
 168 
 169     g_return_val_if_fail (mc_config != NULL, FALSE);
 170 
 171     value = g_key_file_get_value (mc_config->handle, group, param, NULL);
 172     ret = value != NULL;
 173     g_free (value);
 174 
 175     return ret;
 176 }
 177 
 178 /* --------------------------------------------------------------------------------------------- */
 179 
 180 gboolean
 181 mc_config_has_group (mc_config_t * mc_config, const char *group)
     /* [previous][next][first][last][top][bottom][index][help]  */
 182 {
 183     if (mc_config == NULL || group == NULL)
 184         return FALSE;
 185 
 186     return g_key_file_has_group (mc_config->handle, group);
 187 }
 188 
 189 /* --------------------------------------------------------------------------------------------- */
 190 
 191 gboolean
 192 mc_config_del_key (mc_config_t * mc_config, const char *group, const gchar * param)
     /* [previous][next][first][last][top][bottom][index][help]  */
 193 {
 194     if (mc_config == NULL || group == NULL || param == NULL)
 195         return FALSE;
 196 
 197     return g_key_file_remove_key (mc_config->handle, group, param, NULL);
 198 }
 199 
 200 /* --------------------------------------------------------------------------------------------- */
 201 
 202 gboolean
 203 mc_config_del_group (mc_config_t * mc_config, const char *group)
     /* [previous][next][first][last][top][bottom][index][help]  */
 204 {
 205     if (mc_config == NULL || group == NULL)
 206         return FALSE;
 207 
 208     return g_key_file_remove_group (mc_config->handle, group, NULL);
 209 }
 210 
 211 /* --------------------------------------------------------------------------------------------- */
 212 
 213 gboolean
 214 mc_config_read_file (mc_config_t * mc_config, const gchar * ini_path, gboolean read_only,
     /* [previous][next][first][last][top][bottom][index][help]  */
 215                      gboolean remove_empty)
 216 {
 217     mc_config_t *tmp_config;
 218     gchar **groups, **curr_grp;
 219     gchar *value;
 220     gboolean ok;
 221 
 222     if (mc_config == NULL)
 223         return FALSE;
 224 
 225     tmp_config = mc_config_init (ini_path, read_only);
 226     if (tmp_config == NULL)
 227         return FALSE;
 228 
 229     groups = mc_config_get_groups (tmp_config, NULL);
 230     ok = (*groups != NULL);
 231 
 232     for (curr_grp = groups; *curr_grp != NULL; curr_grp++)
 233     {
 234         gchar **keys, **curr_key;
 235 
 236         keys = mc_config_get_keys (tmp_config, *curr_grp, NULL);
 237 
 238         for (curr_key = keys; *curr_key != NULL; curr_key++)
 239         {
 240             value = g_key_file_get_value (tmp_config->handle, *curr_grp, *curr_key, NULL);
 241             if (value != NULL)
 242             {
 243                 if (*value == '\0' && remove_empty)
 244                     g_key_file_remove_key (mc_config->handle, *curr_grp, *curr_key, NULL);
 245                 else
 246                     g_key_file_set_value (mc_config->handle, *curr_grp, *curr_key, value);
 247                 g_free (value);
 248             }
 249             else if (remove_empty)
 250                 g_key_file_remove_key (mc_config->handle, *curr_grp, *curr_key, NULL);
 251         }
 252         g_strfreev (keys);
 253     }
 254 
 255     g_strfreev (groups);
 256     mc_config_deinit (tmp_config);
 257 
 258     return ok;
 259 }
 260 
 261 /* --------------------------------------------------------------------------------------------- */
 262 
 263 gboolean
 264 mc_config_save_file (mc_config_t * mc_config, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 265 {
 266     mc_return_val_if_error (mcerror, FALSE);
 267 
 268     if (mc_config == NULL || mc_config->ini_path == NULL)
 269         return FALSE;
 270 
 271     return mc_config_new_or_override_file (mc_config, mc_config->ini_path, mcerror);
 272 }
 273 
 274 /* --------------------------------------------------------------------------------------------- */
 275 
 276 gboolean
 277 mc_config_save_to_file (mc_config_t * mc_config, const gchar * ini_path, GError ** mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 278 {
 279     mc_return_val_if_error (mcerror, FALSE);
 280 
 281     if (mc_config == NULL)
 282         return FALSE;
 283 
 284     return mc_config_new_or_override_file (mc_config, ini_path, mcerror);
 285 }
 286 
 287 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */