diff --git a/lib/gis/locale.c b/lib/gis/locale.c index f1aabf31f71..16b9acd289c 100644 --- a/lib/gis/locale.c +++ b/lib/gis/locale.c @@ -39,7 +39,9 @@ void G_init_locale(void) #ifdef LC_MESSAGES setlocale(LC_MESSAGES, ""); #endif - const char *localedir = G_locale_dir(); + /* Not using G_locale_dir(): its G_fatal_error() would translate the + message and re-enter G_init_locale(), recursing without bound. */ + const char *localedir = getenv("GRASS_LOCALEDIR"); if (localedir && *localedir) { bindtextdomain("grasslibs", localedir); diff --git a/lib/gis/resource_dirs.c b/lib/gis/resource_dirs.c index 8602ceefe49..8560cb4b671 100644 --- a/lib/gis/resource_dirs.c +++ b/lib/gis/resource_dirs.c @@ -10,44 +10,61 @@ SPDX-License-Identifier: GPL-2.0-or-later */ +#include #include +#include #include #include -static const char *get_g_env(const char *); +static const char *get_g_env(const char *, const char *); const char *G_colors_dir(void) { - return get_g_env("GRASS_COLORSDIR"); + return get_g_env("GRASS_COLORSDIR", "etc/colors"); } const char *G_etcbin_dir(void) { - return get_g_env("GRASS_ETCBINDIR"); + return get_g_env("GRASS_ETCBINDIR", "etc"); } const char *G_etc_dir(void) { - return get_g_env("GRASS_ETCDIR"); + return get_g_env("GRASS_ETCDIR", "etc"); } const char *G_fonts_dir(void) { - return get_g_env("GRASS_FONTSDIR"); + return get_g_env("GRASS_FONTSDIR", "fonts"); } const char *G_locale_dir(void) { - return get_g_env("GRASS_LOCALEDIR"); + return get_g_env("GRASS_LOCALEDIR", "locale"); } -static const char *get_g_env(const char *env_var) +/*! + \brief Get a resource directory from the environment. + + Falls back to the legacy (non-FHS) location relative to GISBASE when + the variable is not set. Fatal when neither yields an existing path. + */ +static const char *get_g_env(const char *env_var, const char *gisbase_rel_dir) { const char *value = getenv(env_var); if (value) return value; + const char *gisbase = getenv("GISBASE"); + if (gisbase && *gisbase) { + char path[GPATH_MAX]; + + snprintf(path, sizeof(path), "%s/%s", gisbase, gisbase_rel_dir); + if (access(path, F_OK) == 0) + return G_store(path); + } + G_fatal_error(_("Incomplete GRASS session: Variable '%s' not set"), env_var); }