Simplify filepath init code

It will no longer attempt to use /home/janssege/.gnucash. That was
requiring lots of extra conditions.
It will also default to a base directory (gnc_data_home) in the
build dir if it detects the code is run during building or testing.
That again allows to simplify it as there's no need for temp dir
juggling in case the build environment doesn't have a writable home dir.
This commit is contained in:
Geert Janssens 2018-02-01 19:17:17 +01:00
parent d345624c55
commit 2f16b092f5
5 changed files with 201 additions and 157 deletions

View File

@ -788,8 +788,10 @@ main(int argc, char ** argv)
gnc_parse_command_line(&argc, &argv); gnc_parse_command_line(&argc, &argv);
gnc_print_unstable_message(); gnc_print_unstable_message();
/* Make sure gnucash' user data directory is properly set up */ /* Make sure gnucash' user data directory is properly set up
userdata_migrated = gnc_filepath_init(TRUE); This must be done before any guile code is called as that would
fail the migration message */
userdata_migrated = gnc_filepath_init();
/* Translators: the message below will be completed with two directory names. */ /* Translators: the message below will be completed with two directory names. */
userdata_migration_msg = g_strdup_printf ( userdata_migration_msg = g_strdup_printf (
_("Notice\n\nYour gnucash metadata has been migrated.\n\n" _("Notice\n\nYour gnucash metadata has been migrated.\n\n"

View File

@ -324,17 +324,12 @@ gnc_path_find_localized_html_file (const gchar *file_name)
* @param dirname The path to check * @param dirname The path to check
*/ */
static bool static bool
gnc_validate_directory (const bfs::path &dirname, bool create) gnc_validate_directory (const bfs::path &dirname)
{ {
if (dirname.empty()) if (dirname.empty())
return false; return false;
if (!bfs::exists(dirname) && (!create)) /* Create directories if they don't exist yet
throw (bfs::filesystem_error("", dirname,
bst::error_code(bst::errc::no_such_file_or_directory,
bst::generic_category())));
/* Optionally create directories if they don't exist yet
* Note this will do nothing if the directory and its * Note this will do nothing if the directory and its
* parents already exist, but will fail if the path * parents already exist, but will fail if the path
* points to a file or a softlink. So it serves as a test * points to a file or a softlink. So it serves as a test
@ -355,16 +350,13 @@ gnc_validate_directory (const bfs::path &dirname, bool create)
#endif #endif
if ((perms & check_perms) != check_perms) if ((perms & check_perms) != check_perms)
throw (bfs::filesystem_error( throw (bfs::filesystem_error(
std::string(_("Insufficient permissions, at least write and access permissions required: ")) std::string("Insufficient permissions, at least write and access permissions required: ")
+ dirname.string(), dirname, + dirname.string(), dirname,
bst::error_code(bst::errc::permission_denied, bst::generic_category()))); bst::error_code(bst::errc::permission_denied, bst::generic_category())));
return true; return true;
} }
static bool userdata_is_home = false;
static bool userdata_is_tmp = false;
static auto userdata_home = bfs::path();
static auto gnc_userdata_home = bfs::path(); static auto gnc_userdata_home = bfs::path();
/* Will attempt to copy all files and directories from src to dest /* Will attempt to copy all files and directories from src to dest
@ -375,6 +367,10 @@ copy_recursive(const bfs::path& src, const bfs::path& dest)
if (!bfs::exists(src)) if (!bfs::exists(src))
return false; return false;
// Don't copy on self
if (src.compare(dest) == 0)
return false;
auto old_str = src.string(); auto old_str = src.string();
auto old_len = old_str.size(); auto old_len = old_str.size();
try try
@ -452,10 +448,11 @@ quarz_get_userdata_home(void)
#endif #endif
static bfs::path static bfs::path
get_userdata_home(bool create) get_userdata_home(void)
{ {
auto try_home_dir = true; auto try_tmp_dir = true;
gchar *data_dir = NULL; gchar *data_dir = NULL;
auto userdata_home = bfs::path();
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
data_dir = win32_get_userdata_home (); data_dir = win32_get_userdata_home ();
@ -471,38 +468,30 @@ get_userdata_home(bool create)
else else
userdata_home = g_get_user_data_dir(); userdata_home = g_get_user_data_dir();
/* g_get_user_data_dir doesn't check whether the path exists nor attempts to
* create it. So while it may return an actual path we may not be able to use it.
* Let's check that now */
if (!userdata_home.empty()) if (!userdata_home.empty())
{ {
try try
{ {
gnc_validate_directory(userdata_home, create); // May throw gnc_validate_directory(userdata_home); // May throw
try_home_dir = false; try_tmp_dir = false;
} }
catch (const bfs::filesystem_error& ex) catch (const bfs::filesystem_error& ex)
{ {
auto path_string = userdata_home.string(); auto path_string = userdata_home.string();
g_warning("%s is not a suitable base directory for the user data. " g_warning("%s is not a suitable base directory for the user data. "
"Trying home directory instead.\n(Error: %s)", "Trying temporary directory instead.\n(Error: %s)",
path_string.c_str(), ex.what()); path_string.c_str(), ex.what());
} }
} }
if (try_home_dir) /* The path we got is not usable, so fall back to a path in TMP_DIR.
Hopefully we can always write there. */
if (try_tmp_dir)
{ {
userdata_home = g_get_home_dir(); userdata_home = bfs::path (g_get_tmp_dir ()) / g_get_user_name ();
try
{
/* Never attempt to create a home directory, hence the false below */
gnc_validate_directory(userdata_home, false); // May throw
userdata_is_home = true;
}
catch (const bfs::filesystem_error& ex)
{
g_warning("Cannot find suitable home directory. Using tmp directory instead.\n"
"(Error: %s)", ex.what());
userdata_home = g_get_tmp_dir();
userdata_is_tmp = true;
}
} }
g_assert(!userdata_home.empty()); g_assert(!userdata_home.empty());
@ -510,11 +499,42 @@ get_userdata_home(bool create)
} }
gboolean gboolean
gnc_filepath_init(gboolean create) gnc_filepath_init (void)
{ {
userdata_is_home = userdata_is_tmp = false;
auto gnc_userdata_home_exists = false; auto gnc_userdata_home_exists = false;
auto gnc_userdata_home_from_env = false; auto have_valid_userdata_home = false;
/* If this code is run while building/testing, use a fake GNC_DATA_HOME
* in the base of the build directory. This is to deal with all kinds of
* issues when the build environment is not a complete environment (like
* it could be missing a valid home directory). */
auto builddir = g_getenv ("GNC_BUILDDIR");
auto running_uninstalled = (g_getenv ("GNC_UNINSTALLED") != NULL);
if (running_uninstalled && builddir)
{
auto build_home = g_build_filename (builddir, "gnc_data_home", NULL);
gnc_userdata_home = bfs::path(build_home);
g_free (build_home);
try
{
gnc_validate_directory(gnc_userdata_home); // May throw
have_valid_userdata_home = true;
gnc_userdata_home_exists = true; // To prevent possible migration further down
}
catch (const bfs::filesystem_error& ex)
{
auto path_string = gnc_userdata_home.string();
g_warning("%s (due to run during at build time) is not a suitable directory for user data. "
"Trying another directory instead.\n(Error: %s)",
path_string.c_str(), ex.what());
}
}
if (!have_valid_userdata_home)
{
/* If environment variable GNC_DATA_HOME is set, try whether
* it points at a valid directory. */
auto gnc_userdata_home_env = g_getenv("GNC_DATA_HOME"); auto gnc_userdata_home_env = g_getenv("GNC_DATA_HOME");
if (gnc_userdata_home_env) if (gnc_userdata_home_env)
{ {
@ -522,78 +542,52 @@ gnc_filepath_init(gboolean create)
try try
{ {
gnc_userdata_home_exists = bfs::exists(gnc_userdata_home); gnc_userdata_home_exists = bfs::exists(gnc_userdata_home);
gnc_validate_directory(gnc_userdata_home, create); // May throw gnc_validate_directory(gnc_userdata_home); // May throw
gnc_userdata_home_from_env = true; have_valid_userdata_home = true;
} }
catch (const bfs::filesystem_error& ex) catch (const bfs::filesystem_error& ex)
{ {
auto path_string = userdata_home.string(); auto path_string = gnc_userdata_home.string();
g_warning("%s (from environment variable 'GNC_DATA_HOME') is not a suitable directory for the user data. " g_warning("%s (from environment variable 'GNC_DATA_HOME') is not a suitable directory for user data. "
"Trying the default instead.\n(Error: %s)", "Trying the default instead.\n(Error: %s)",
path_string.c_str(), ex.what()); path_string.c_str(), ex.what());
} }
} }
if (!gnc_userdata_home_from_env)
{
auto userdata_home = get_userdata_home(create);
if (userdata_is_home)
{
/* If we get here that means the platform
* dependent gnc_userdata_home is not available for
* some reason. If legacy .gnucash directory still exists,
* use it as first fallback, but never create it (we want
* it to go away eventually).
* If missing, fall back to tmp_dir instead */
gnc_userdata_home = userdata_home / ".gnucash";
if (!bfs::exists(gnc_userdata_home))
{
userdata_home = g_get_tmp_dir();
userdata_is_home = false;
userdata_is_tmp = true;
}
} }
/* The fall back to the tmp dir is to accomodate for very restricted if (!have_valid_userdata_home)
* distribution build environments. In some such cases {
* there is no home directory available, which would cause the build /* Determine platform dependent default userdata_home_path
* to fail (as this code is actually run while compiling guile scripts). * and check whether it's valid */
* This is worked around by continuing with a userdata directory auto userdata_home = get_userdata_home();
* in the temporary directory which always exists. */ gnc_userdata_home = userdata_home / PACKAGE;
if (!userdata_is_home)
gnc_userdata_home = userdata_home / PACKAGE_NAME;
gnc_userdata_home_exists = bfs::exists(gnc_userdata_home);
/* This may throw and end the program!
* Note we always allow to create in the tmp_dir. This will
* skip migrating to that location in the next step but that's
* a good thing.
*/
try try
{ {
gnc_validate_directory(gnc_userdata_home, (create || userdata_is_tmp)); gnc_userdata_home_exists = bfs::exists(gnc_userdata_home);
gnc_validate_directory(gnc_userdata_home);
} }
catch (const bfs::filesystem_error& ex) catch (const bfs::filesystem_error& ex)
{ {
g_warning("User data directory doesn't exist, yet the calling code requested not to create it. Proceed with caution.\n" g_warning("User data directory doesn't exist, yet could not be created. Proceed with caution.\n"
"(Error: %s)", ex.what()); "(Error: %s)", ex.what());
} }
} }
auto migrated = FALSE; auto migrated = FALSE;
if (!userdata_is_home && !gnc_userdata_home_exists && create) if (!gnc_userdata_home_exists)
migrated = copy_recursive(bfs::path (g_get_home_dir()) / ".gnucash", migrated = copy_recursive(bfs::path (g_get_home_dir()) / ".gnucash",
gnc_userdata_home); gnc_userdata_home);
/* Try to create the standard subdirectories for gnucash' user data */ /* Try to create the standard subdirectories for gnucash' user data */
try try
{ {
gnc_validate_directory(gnc_userdata_home / "books", (create || userdata_is_tmp)); gnc_validate_directory(gnc_userdata_home / "books");
gnc_validate_directory(gnc_userdata_home / "checks", (create || userdata_is_tmp)); gnc_validate_directory(gnc_userdata_home / "checks");
gnc_validate_directory(gnc_userdata_home / "translog", (create || userdata_is_tmp)); gnc_validate_directory(gnc_userdata_home / "translog");
} }
catch (const bfs::filesystem_error& ex) catch (const bfs::filesystem_error& ex)
{ {
g_warning("Default user data subdirectories don't exist, yet the calling code requested not to create them. Proceed with caution.\n" g_warning("Default user data subdirectories don't exist, yet could not be created. Proceed with caution.\n"
"(Error: %s)", ex.what()); "(Error: %s)", ex.what());
} }
@ -642,7 +636,7 @@ const gchar *
gnc_userdata_dir (void) gnc_userdata_dir (void)
{ {
if (gnc_userdata_home.empty()) if (gnc_userdata_home.empty())
gnc_filepath_init(false); gnc_filepath_init();
return gnc_userdata_home.string().c_str(); return gnc_userdata_home.string().c_str();
} }
@ -657,7 +651,7 @@ gnc_userdata_dir_as_path (void)
* code most likely) very early in application startup. * code most likely) very early in application startup.
* This call is just a fallback to prevent the code from * This call is just a fallback to prevent the code from
* crashing because no directories were configured. */ * crashing because no directories were configured. */
gnc_filepath_init(false); gnc_filepath_init();
return gnc_userdata_home; return gnc_userdata_home;
} }

View File

@ -87,22 +87,13 @@ gchar *gnc_path_find_localized_html_file (const gchar *file_name);
* This function should be called very early at startup (before any * This function should be called very early at startup (before any
* other of the user data directory related function gets called). * other of the user data directory related function gets called).
* *
* @param create If true the function will attempt to create the
* gnucash user data directory its subdirectories and parent directories
* if they don't exist yet. Note it won't attempt to create a home directory
* if that is missing. In that case the system's default temporary
* directory will be used instead. If false it will not attempt to create
* any directories at all unless they are in the temporary directory. This
* is a fallback measure to allow the calling application to more or less
* function even if gnc_filepath_init was never called.
*
* @note If the necessary directories did get created this * @note If the necessary directories did get created this
* function will also try to copy files from $HOME/.gnucash * function will also try to copy files from $HOME/.gnucash
* to there if that old location exists. * to there if that old location exists.
* *
* @return whether files got copied from the old location. * @return whether files got copied from the old location.
*/ */
gboolean gnc_filepath_init(gboolean create); gboolean gnc_filepath_init (void);
const gchar *gnc_userdata_dir (void); const gchar *gnc_userdata_dir (void);
gchar *gnc_build_userdata_path (const gchar *filename); gchar *gnc_build_userdata_path (const gchar *filename);

View File

@ -42,19 +42,19 @@ usr_confpath_strings strs2[] =
{ {
{ {
0, "gnc_build_userdata_path", 0, "gnc_build_userdata_path",
PACKAGE_NAME PACKAGE
}, },
{ {
1, "gnc_build_book_path", 1, "gnc_build_book_path",
PACKAGE_NAME G_DIR_SEPARATOR_S "books" PACKAGE G_DIR_SEPARATOR_S "books"
}, },
{ {
2, "gnc_build_translog_path", 2, "gnc_build_translog_path",
PACKAGE_NAME G_DIR_SEPARATOR_S "translog" PACKAGE G_DIR_SEPARATOR_S "translog"
}, },
{ {
3, "gnc_build_data_path", 3, "gnc_build_data_path",
PACKAGE_NAME G_DIR_SEPARATOR_S "data" PACKAGE G_DIR_SEPARATOR_S "data"
}, },
{ 0, NULL, NULL }, { 0, NULL, NULL },
}; };
@ -62,9 +62,21 @@ usr_confpath_strings strs2[] =
int int
main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
{ {
/* Don't run this test on Windows or OS X. This
test attempts to fool the code into using a non-existent
home directory, but the way this is done only works on linux
*/
#ifndef MAC_INTEGRATION
#ifndef G_OS_WIN32
int i; int i;
const char *tmp_dir = g_get_tmp_dir(); const char *tmp_dir = g_get_tmp_dir();
/* Assume we're not in a build environment to test
* the function's actual behaviour in a real world use case, using
* a non-existent homedir. */
g_unsetenv("GNC_BUILDDIR");
g_unsetenv("GNC_UNINSTALLED");
/* Run usr conf dir tests with an invalid homedir /* Run usr conf dir tests with an invalid homedir
* The code should fall back to using the temporary * The code should fall back to using the temporary
* directory in that case. */ * directory in that case. */
@ -76,25 +88,25 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
if (strs2[i].func_num == 0) if (strs2[i].func_num == 0)
{ {
wantout = g_build_filename(tmp_dir, strs2[i].output, "foo", wantout = g_build_filename(tmp_dir, g_get_user_name (), strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_userdata_path("foo"); daout = gnc_build_userdata_path("foo");
} }
else if (strs2[i].func_num == 1) else if (strs2[i].func_num == 1)
{ {
wantout = g_build_filename(tmp_dir, strs2[i].output, "foo", wantout = g_build_filename(tmp_dir, g_get_user_name (), strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_book_path("foo"); daout = gnc_build_book_path("foo");
} }
else if (strs2[i].func_num == 2) else if (strs2[i].func_num == 2)
{ {
wantout = g_build_filename(tmp_dir, strs2[i].output, "foo", wantout = g_build_filename(tmp_dir, g_get_user_name (), strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_translog_path("foo"); daout = gnc_build_translog_path("foo");
} }
else // if (strs2[i].prefix_home == 3) else // if (strs2[i].prefix_home == 3)
{ {
wantout = g_build_filename(tmp_dir, strs2[i].output, "foo", wantout = g_build_filename(tmp_dir, g_get_user_name (), strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_data_path("foo"); daout = gnc_build_data_path("foo");
} }
@ -109,4 +121,6 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
print_test_results(); print_test_results();
return get_rv(); return get_rv();
#endif
#endif
} }

View File

@ -87,6 +87,8 @@ main(int argc, char **argv)
char *tmp_dir = NULL; char *tmp_dir = NULL;
char *userdata_dir = NULL; char *userdata_dir = NULL;
char *gnc_data_home_dir = NULL; char *gnc_data_home_dir = NULL;
const char *builddir = g_getenv("GNC_BUILDDIR");
const char *uninstalled = g_getenv("GNC_UNINSTALLED");
if (argc > 1) if (argc > 1)
{ {
@ -96,23 +98,22 @@ main(int argc, char **argv)
* test error messages should then show the system's temporary * test error messages should then show the system's temporary
* directory to be used instead */ * directory to be used instead */
home_dir = g_strdup(argv[1]); home_dir = g_strdup(argv[1]);
tmp_dir = g_strdup(g_get_tmp_dir());
} }
else else
{ {
/* Set up a fake home directory to play with */ /* Set up a fake home directory to play with */
#ifdef MAC_INTEGRATION #ifdef MAC_INTEGRATION
home_dir = test_get_userdatadir(); home_dir = test_get_userdatadir();
tmp_dir = g_strdup(home_dir);
#else #else
home_dir = g_dir_make_tmp("gnucashXXXXXX", NULL); home_dir = g_dir_make_tmp("gnucashXXXXXX", NULL);
tmp_dir = g_strdup(g_get_tmp_dir());
#endif #endif
} }
/* Run usr conf dir tests with a valid and writable homedir */ /* Run usr conf dir tests with a valid and writable fake homedir */
g_setenv("HOME", home_dir, TRUE); g_setenv("HOME", home_dir, TRUE);
/* First run, before calling gnc_filepath_init */ /* First run, assuming GNC_BUILDDIR and GNC_UNINSTALLED are set */
if (builddir && uninstalled)
{
for (i = 0; strs2[i].funcname != NULL; i++) for (i = 0; strs2[i].funcname != NULL; i++)
{ {
char *daout; char *daout;
@ -120,25 +121,25 @@ main(int argc, char **argv)
if (strs2[i].func_num == 0) if (strs2[i].func_num == 0)
{ {
wantout = g_build_filename(tmp_dir, PACKAGE_NAME, "foo", wantout = g_build_filename(builddir, "gnc_data_home", "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_userdata_path("foo"); daout = gnc_build_userdata_path("foo");
} }
else if (strs2[i].func_num == 1) else if (strs2[i].func_num == 1)
{ {
wantout = g_build_filename(tmp_dir, PACKAGE_NAME, strs2[i].output, "foo", wantout = g_build_filename(builddir, "gnc_data_home", strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_book_path("foo"); daout = gnc_build_book_path("foo");
} }
else if (strs2[i].func_num == 2) else if (strs2[i].func_num == 2)
{ {
wantout = g_build_filename(tmp_dir, PACKAGE_NAME, strs2[i].output, "foo", wantout = g_build_filename(builddir, "gnc_data_home", strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_translog_path("foo"); daout = gnc_build_translog_path("foo");
} }
else // if (strs2[i].prefix_home == 3) else // if (strs2[i].prefix_home == 3)
{ {
wantout = g_build_filename(tmp_dir, PACKAGE_NAME, strs2[i].output, "foo", wantout = g_build_filename(builddir, "gnc_data_home", strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_data_path("foo"); daout = gnc_build_data_path("foo");
} }
@ -150,6 +151,14 @@ main(int argc, char **argv)
g_free(wantout); g_free(wantout);
g_free(daout); g_free(daout);
} }
}
/* Further tests should be run assuming we're not in a build environment to test
* the function's actual behaviour in a real world use case, but still using
* the fake, writable homedir. */
g_unsetenv("GNC_BUILDDIR");
g_unsetenv("GNC_UNINSTALLED");
/* Second run, with existing userdata_dir, but without the GnuCash subdir /* Second run, with existing userdata_dir, but without the GnuCash subdir
This test can not be run on OS X or Windows, as our code is not using This test can not be run on OS X or Windows, as our code is not using
@ -159,7 +168,7 @@ main(int argc, char **argv)
userdata_dir = g_build_filename(home_dir, ".local", "share", (gchar *)NULL); userdata_dir = g_build_filename(home_dir, ".local", "share", (gchar *)NULL);
g_mkdir_with_parents(userdata_dir, 0750); g_mkdir_with_parents(userdata_dir, 0750);
g_setenv("XDG_DATA_HOME", userdata_dir, TRUE); g_setenv("XDG_DATA_HOME", userdata_dir, TRUE);
gnc_filepath_init(FALSE); gnc_filepath_init();
for (i = 0; strs2[i].funcname != NULL; i++) for (i = 0; strs2[i].funcname != NULL; i++)
{ {
char *daout; char *daout;
@ -167,25 +176,25 @@ main(int argc, char **argv)
if (strs2[i].func_num == 0) if (strs2[i].func_num == 0)
{ {
wantout = g_build_filename(userdata_dir, PACKAGE_NAME, "foo", wantout = g_build_filename(userdata_dir, PACKAGE, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_userdata_path("foo"); daout = gnc_build_userdata_path("foo");
} }
else if (strs2[i].func_num == 1) else if (strs2[i].func_num == 1)
{ {
wantout = g_build_filename(userdata_dir, PACKAGE_NAME, strs2[i].output, "foo", wantout = g_build_filename(userdata_dir, PACKAGE, strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_book_path("foo"); daout = gnc_build_book_path("foo");
} }
else if (strs2[i].func_num == 2) else if (strs2[i].func_num == 2)
{ {
wantout = g_build_filename(userdata_dir, PACKAGE_NAME, strs2[i].output, "foo", wantout = g_build_filename(userdata_dir, PACKAGE, strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_translog_path("foo"); daout = gnc_build_translog_path("foo");
} }
else // if (strs2[i].prefix_home == 3) else // if (strs2[i].prefix_home == 3)
{ {
wantout = g_build_filename(userdata_dir, PACKAGE_NAME, strs2[i].output, "foo", wantout = g_build_filename(userdata_dir, PACKAGE, strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_data_path("foo"); daout = gnc_build_data_path("foo");
} }
@ -197,20 +206,32 @@ main(int argc, char **argv)
g_free(wantout); g_free(wantout);
g_free(daout); g_free(daout);
} }
/* Remove intermediate directories again in order to test their automatic g_unsetenv("XDG_DATA_HOME");
* creation in the next test run */ /* Remove intermediate directories again */
g_rmdir(userdata_dir); tmp_dir = g_build_filename(userdata_dir, PACKAGE, "data", (gchar *)NULL);
g_free(userdata_dir); g_rmdir (tmp_dir);
userdata_dir = g_build_filename(home_dir, ".local", (gchar *)NULL); g_free (tmp_dir);
tmp_dir = g_build_filename(userdata_dir, PACKAGE, "translog", (gchar *)NULL);
g_rmdir (tmp_dir);
g_free (tmp_dir);
tmp_dir = g_build_filename(userdata_dir, PACKAGE, "books", (gchar *)NULL);
g_rmdir (tmp_dir);
g_free (tmp_dir);
tmp_dir = g_build_filename(userdata_dir, PACKAGE, (gchar *)NULL);
g_rmdir (tmp_dir);
g_free (tmp_dir);
g_rmdir(userdata_dir); g_rmdir(userdata_dir);
tmp_dir = g_path_get_dirname(userdata_dir);
g_rmdir(tmp_dir);
g_free (tmp_dir);
g_free(userdata_dir); g_free(userdata_dir);
#endif #endif
#endif #endif
/* Third run, with GNC_DATA_HOME not set and having run gnc_filepath_init */ /* Third run, with neither XDG_DATA_HOME nor GNC_DATA_HOME set */
g_unsetenv("GNC_DATA_HOME"); g_unsetenv("GNC_DATA_HOME");
gnc_filepath_init(TRUE);
userdata_dir = test_get_userdatadir(); userdata_dir = test_get_userdatadir();
gnc_filepath_init();
for (i = 0; strs2[i].funcname != NULL; i++) for (i = 0; strs2[i].funcname != NULL; i++)
{ {
char *daout; char *daout;
@ -218,25 +239,25 @@ main(int argc, char **argv)
if (strs2[i].func_num == 0) if (strs2[i].func_num == 0)
{ {
wantout = g_build_filename(userdata_dir, PACKAGE_NAME, "foo", wantout = g_build_filename(userdata_dir, PACKAGE, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_userdata_path("foo"); daout = gnc_build_userdata_path("foo");
} }
else if (strs2[i].func_num == 1) else if (strs2[i].func_num == 1)
{ {
wantout = g_build_filename(userdata_dir, PACKAGE_NAME, strs2[i].output, "foo", wantout = g_build_filename(userdata_dir, PACKAGE, strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_book_path("foo"); daout = gnc_build_book_path("foo");
} }
else if (strs2[i].func_num == 2) else if (strs2[i].func_num == 2)
{ {
wantout = g_build_filename(userdata_dir, PACKAGE_NAME, strs2[i].output, "foo", wantout = g_build_filename(userdata_dir, PACKAGE, strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_translog_path("foo"); daout = gnc_build_translog_path("foo");
} }
else // if (strs2[i].prefix_home == 3) else // if (strs2[i].prefix_home == 3)
{ {
wantout = g_build_filename(userdata_dir, PACKAGE_NAME, strs2[i].output, "foo", wantout = g_build_filename(userdata_dir, PACKAGE, strs2[i].output, "foo",
(gchar *)NULL); (gchar *)NULL);
daout = gnc_build_data_path("foo"); daout = gnc_build_data_path("foo");
} }
@ -248,12 +269,34 @@ main(int argc, char **argv)
g_free(wantout); g_free(wantout);
g_free(daout); g_free(daout);
} }
/* Remove intermediate directories again */
tmp_dir = g_build_filename(userdata_dir, PACKAGE, "data", (gchar *)NULL);
g_rmdir (tmp_dir);
g_free (tmp_dir);
tmp_dir = g_build_filename(userdata_dir, PACKAGE, "translog", (gchar *)NULL);
g_rmdir (tmp_dir);
g_free (tmp_dir);
tmp_dir = g_build_filename(userdata_dir, PACKAGE, "books", (gchar *)NULL);
g_rmdir (tmp_dir);
g_free (tmp_dir);
#ifndef MAC_INTEGRATION
#ifndef G_OS_WIN32
/* Don't delete these on OS X or Windows. They may point at real user directories */
tmp_dir = g_build_filename(userdata_dir, PACKAGE, (gchar *)NULL);
g_rmdir (tmp_dir);
g_free (tmp_dir);
g_rmdir(userdata_dir);
tmp_dir = g_path_get_dirname(userdata_dir);
g_rmdir(tmp_dir);
g_free (tmp_dir);
#endif
#endif
g_free(userdata_dir); g_free(userdata_dir);
/* Fourth run, with GNC_DATA_HOME set and having run gnc_filepath_init */ /* Fourth run, with GNC_DATA_HOME */
gnc_data_home_dir = g_build_filename(home_dir, "Test", NULL); gnc_data_home_dir = g_build_filename(home_dir, "Test", NULL);
g_setenv("GNC_DATA_HOME", gnc_data_home_dir, TRUE); g_setenv("GNC_DATA_HOME", gnc_data_home_dir, TRUE);
gnc_filepath_init(TRUE); gnc_filepath_init();
for (i = 0; strs2[i].funcname != NULL; i++) for (i = 0; strs2[i].funcname != NULL; i++)
{ {
char *daout; char *daout;