Manual pages: mcmcdiffmceditmcview

root/lib/mcconfig/paths.c

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

DEFINITIONS

This source file includes following definitions.
  1. mc_config_mkdir
  2. mc_config_init_one_config_path
  3. mc_config_init_config_paths
  4. mc_config_deinit_config_paths
  5. mc_config_get_data_path
  6. mc_config_get_cache_path
  7. mc_config_get_home_dir
  8. mc_config_get_path
  9. mc_config_get_full_path
  10. mc_config_get_full_vpath

   1 /*
   2    paths to configuration files
   3 
   4    Copyright (C) 2010-2026
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Slava Zanko <slavazanko@gmail.com>, 2010.
   9 
  10    This file is part of the Midnight Commander.
  11 
  12    The Midnight Commander is free software: you can redistribute it
  13    and/or modify it under the terms of the GNU General Public License as
  14    published by the Free Software Foundation, either version 3 of the License,
  15    or (at your option) any later version.
  16 
  17    The Midnight Commander is distributed in the hope that it will be useful,
  18    but WITHOUT ANY WARRANTY; without even the implied warranty of
  19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20    GNU General Public License for more details.
  21 
  22    You should have received a copy of the GNU General Public License
  23    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  24  */
  25 
  26 #include <config.h>
  27 
  28 #include <stdio.h>
  29 #include <stdlib.h>
  30 
  31 #include "lib/global.h"
  32 #include "lib/fileloc.h"
  33 #include "lib/vfs/vfs.h"
  34 #include "lib/util.h"  // unix_error_string()
  35 
  36 #include "lib/mcconfig.h"
  37 
  38 /*** global variables ****************************************************************************/
  39 
  40 /*** file scope macro definitions ****************************************************************/
  41 
  42 /*** file scope type declarations ****************************************************************/
  43 
  44 /*** forward declarations (file scope functions) *************************************************/
  45 
  46 /*** file scope variables ************************************************************************/
  47 
  48 static gboolean xdg_vars_initialized = FALSE;
  49 static char *mc_config_str = NULL;
  50 static char *mc_cache_str = NULL;
  51 static char *mc_data_str = NULL;
  52 
  53 static const struct
  54 {
  55     char **basedir;
  56     const char *filename;
  57 } mc_config_files_reference[] = {
  58     // config
  59     { &mc_config_str, MC_CONFIG_FILE },
  60     { &mc_config_str, MC_FHL_INI_FILE },
  61     { &mc_config_str, MC_HOTLIST_FILE },
  62     { &mc_config_str, GLOBAL_KEYMAP_FILE },
  63     { &mc_config_str, MC_USERMENU_FILE },
  64     { &mc_config_str, EDIT_HOME_MENU },
  65     { &mc_config_str, MC_PANELS_FILE },
  66 
  67     // User should move this file with applying some changes in file
  68     { &mc_config_str, MC_EXT_FILE },
  69     { &mc_config_str, MC_EXT_OLD_FILE },
  70 
  71     // data
  72     { &mc_data_str, MC_SKINS_DIR },
  73     { &mc_data_str, VFS_SHELL_PREFIX },
  74     { &mc_data_str, MC_ASHRC_CUSTOM_PROFILE_FILE },
  75     { &mc_data_str, MC_KSHRC_CUSTOM_PROFILE_FILE },
  76     { &mc_data_str, MC_MKSHRC_CUSTOM_PROFILE_FILE },
  77     { &mc_data_str, MC_BASHRC_CUSTOM_PROFILE_FILE },
  78     { &mc_data_str, MC_INPUTRC_FILE },
  79     { &mc_data_str, MC_ZSHRC_CUSTOM_PROFILE_FILE },
  80     { &mc_data_str, MC_EXTFS_DIR },
  81     { &mc_data_str, MC_HISTORY_FILE },
  82     { &mc_data_str, MC_FILEPOS_FILE },
  83     { &mc_data_str, EDIT_SYNTAX_FILE },
  84     { &mc_data_str, EDIT_HOME_CLIP_FILE },
  85     { &mc_data_str, MC_MACRO_FILE },
  86 
  87     // cache
  88     { &mc_cache_str, "mc.log" },
  89     { &mc_cache_str, MC_TREESTORE_FILE },
  90     { &mc_cache_str, EDIT_HOME_TEMP_FILE },
  91     { &mc_cache_str, EDIT_HOME_BLOCK_FILE },
  92 
  93     {
  94         NULL,
  95         NULL,
  96     },
  97 };
  98 
  99 /* --------------------------------------------------------------------------------------------- */
 100 /*** file scope functions *********************************************************************** */
 101 /* --------------------------------------------------------------------------------------------- */
 102 
 103 static void
 104 mc_config_mkdir (const char *directory_name, GError **mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 105 {
 106     mc_return_if_error (mcerror);
 107 
 108     if (!(g_file_test (directory_name, G_FILE_TEST_EXISTS)
 109           && g_file_test (directory_name, G_FILE_TEST_IS_DIR))
 110         && g_mkdir_with_parents (directory_name, 0700) != 0)
 111         mc_propagate_error (mcerror, 0, _ ("Cannot create %s directory"), directory_name);
 112 }
 113 
 114 /* --------------------------------------------------------------------------------------------- */
 115 
 116 static char *
 117 mc_config_init_one_config_path (const char *path_base, const char *subdir, GError **mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 118 {
 119     char *full_path;
 120 
 121     mc_return_val_if_error (mcerror, FALSE);
 122 
 123     full_path = g_build_filename (path_base, subdir, (char *) NULL);
 124 
 125     if (g_file_test (full_path, G_FILE_TEST_EXISTS) && !g_file_test (full_path, G_FILE_TEST_IS_DIR))
 126     {
 127         fprintf (stderr, "%s %s\n", _ ("FATAL: not a directory:"), full_path);
 128         exit (EXIT_FAILURE);
 129     }
 130 
 131     mc_config_mkdir (full_path, mcerror);
 132     if (mcerror != NULL && *mcerror != NULL)
 133         MC_PTR_FREE (full_path);
 134 
 135     return full_path;
 136 }
 137 
 138 /* --------------------------------------------------------------------------------------------- */
 139 /*** public functions ****************************************************************************/
 140 /* --------------------------------------------------------------------------------------------- */
 141 
 142 void
 143 mc_config_init_config_paths (GError **mcerror)
     /* [previous][next][first][last][top][bottom][index][help]  */
 144 {
 145     const char *profile_root;
 146     char *dir;
 147 
 148     mc_return_if_error (mcerror);
 149 
 150     if (xdg_vars_initialized)
 151         return;
 152 
 153     profile_root = mc_get_profile_root ();
 154 
 155     if (strcmp (profile_root, mc_config_get_home_dir ()) != 0)
 156     {
 157         /*
 158          * The user overrode the default profile root.
 159          *
 160          * In this case we can't use GLib's g_get_user_{config,cache,data}_dir()
 161          * as these functions use the user's home dir as the root.
 162          */
 163 
 164         dir = g_build_filename (profile_root, ".config", (char *) NULL);
 165         mc_config_str = mc_config_init_one_config_path (dir, MC_USERCONF_DIR, mcerror);
 166         g_free (dir);
 167 
 168         dir = g_build_filename (profile_root, ".cache", (char *) NULL);
 169         mc_cache_str = mc_config_init_one_config_path (dir, MC_USERCONF_DIR, mcerror);
 170         g_free (dir);
 171 
 172         dir = g_build_filename (profile_root, ".local", "share", (char *) NULL);
 173         mc_data_str = mc_config_init_one_config_path (dir, MC_USERCONF_DIR, mcerror);
 174         g_free (dir);
 175     }
 176     else
 177     {
 178         mc_config_str =
 179             mc_config_init_one_config_path (g_get_user_config_dir (), MC_USERCONF_DIR, mcerror);
 180         mc_cache_str =
 181             mc_config_init_one_config_path (g_get_user_cache_dir (), MC_USERCONF_DIR, mcerror);
 182         mc_data_str =
 183             mc_config_init_one_config_path (g_get_user_data_dir (), MC_USERCONF_DIR, mcerror);
 184     }
 185 
 186     xdg_vars_initialized = TRUE;
 187 }
 188 
 189 /* --------------------------------------------------------------------------------------------- */
 190 
 191 void
 192 mc_config_deinit_config_paths (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 193 {
 194     if (!xdg_vars_initialized)
 195         return;
 196 
 197     g_free (mc_config_str);
 198     g_free (mc_cache_str);
 199     g_free (mc_data_str);
 200 
 201     g_free (mc_global.share_data_dir);
 202     g_free (mc_global.sysconfig_dir);
 203 
 204     xdg_vars_initialized = FALSE;
 205 }
 206 
 207 /* --------------------------------------------------------------------------------------------- */
 208 
 209 const char *
 210 mc_config_get_data_path (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 211 {
 212     if (!xdg_vars_initialized)
 213         mc_config_init_config_paths (NULL);
 214 
 215     return (const char *) mc_data_str;
 216 }
 217 
 218 /* --------------------------------------------------------------------------------------------- */
 219 
 220 const char *
 221 mc_config_get_cache_path (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 222 {
 223     if (!xdg_vars_initialized)
 224         mc_config_init_config_paths (NULL);
 225 
 226     return (const char *) mc_cache_str;
 227 }
 228 
 229 /* --------------------------------------------------------------------------------------------- */
 230 
 231 const char *
 232 mc_config_get_home_dir (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 233 {
 234     static const char *homedir = NULL;
 235 
 236     if (homedir == NULL)
 237     {
 238         /* Prior to GLib 2.36, g_get_home_dir() ignores $HOME, which is why
 239          * we read it ourselves. As that function's documentation explains,
 240          * using $HOME is good for compatibility with other programs and
 241          * for running from test frameworks. */
 242         homedir = g_getenv ("HOME");
 243         if (homedir == NULL || *homedir == '\0')
 244             homedir = g_get_home_dir ();
 245     }
 246 
 247     return homedir;
 248 }
 249 
 250 /* --------------------------------------------------------------------------------------------- */
 251 
 252 const char *
 253 mc_config_get_path (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 254 {
 255     if (!xdg_vars_initialized)
 256         mc_config_init_config_paths (NULL);
 257 
 258     return (const char *) mc_config_str;
 259 }
 260 
 261 /* --------------------------------------------------------------------------------------------- */
 262 /**
 263  * Get full path to config file by short name.
 264  *
 265  * @param config_name short name
 266  * @return full path to config file
 267  */
 268 
 269 char *
 270 mc_config_get_full_path (const char *config_name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 271 {
 272     size_t rule_index;
 273 
 274     if (config_name == NULL)
 275         return NULL;
 276 
 277     if (!xdg_vars_initialized)
 278         mc_config_init_config_paths (NULL);
 279 
 280     for (rule_index = 0; mc_config_files_reference[rule_index].filename != NULL; rule_index++)
 281         if (strcmp (config_name, mc_config_files_reference[rule_index].filename) == 0)
 282             return g_build_filename (*mc_config_files_reference[rule_index].basedir,
 283                                      mc_config_files_reference[rule_index].filename, (char *) NULL);
 284 
 285     return NULL;
 286 }
 287 
 288 /* --------------------------------------------------------------------------------------------- */
 289 /**
 290  * Get full path to config file by short name.
 291  *
 292  * @param config_name short name
 293  * @return object with full path to config file
 294  */
 295 
 296 vfs_path_t *
 297 mc_config_get_full_vpath (const char *config_name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 298 {
 299     vfs_path_t *ret_vpath;
 300     char *str_path;
 301 
 302     str_path = mc_config_get_full_path (config_name);
 303 
 304     ret_vpath = vfs_path_from_str (str_path);
 305     g_free (str_path);
 306 
 307     return ret_vpath;
 308 }
 309 
 310 /* --------------------------------------------------------------------------------------------- */

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