diff --git a/src/app-utils/file-utils.c b/src/app-utils/file-utils.c index 456e95243a..899959698e 100644 --- a/src/app-utils/file-utils.c +++ b/src/app-utils/file-utils.c @@ -177,18 +177,30 @@ gnc_getline (gchar **line, FILE *file) return len; } -/* Find the state file that corresponds to this URL and guid. The - * URL is used to compute the base name of the file (which will be in - * ~/.gnucash/books) and the guid is used to differentiate when the - * user has multiple data files with the same name. */ +/* Find the state file that corresponds to this URL and guid. + * + * The state files will be searched for in the books directory in GnuCash' + * private configuration directory. This configuration directory is + * platform dependent and can be overridden with environment variable + * DOT_GNUCASH_DIR. On linux for example this is ~/.gnucash by default. + * + * The URL is used to compute the base name of the state file and the + * guid is used to differentiate when the user has multiple data files + * with the same name. + * + * As of GnuCash 2.4.1 state files will have their own extension to + * differentiate them from data files saved by the user. New state + * files will always be created with such an extension. But GnuCash + * will continue to search for state files without an extension if + * no proper state file with extension is found. */ GKeyFile * gnc_find_state_file (const gchar *url, const gchar *guid, gchar **filename_p) { gchar *basename, *original = NULL, *filename, *tmp, *file_guid; + gchar *sf_extension = NULL, *newstyle_filename = NULL; GKeyFile *key_file = NULL; - gboolean do_increment = FALSE; gint i; ENTER("url %s, guid %s", url, guid); @@ -225,13 +237,14 @@ gnc_find_state_file (const gchar *url, g_free(basename); DEBUG("Original %s", original); + sf_extension = g_strdup(STATE_FILE_EXT); i = 1; while (1) { if (i == 1) - filename = g_strdup(original); + filename = g_strconcat(original, sf_extension, NULL); else - filename = g_strdup_printf("%s_%d", original, i); + filename = g_strdup_printf("%s_%d%s", original, i, sf_extension); DEBUG("Trying %s", filename); key_file = gnc_key_file_load_from_file(filename, FALSE, FALSE, NULL); DEBUG("Result %p", key_file); @@ -239,6 +252,15 @@ gnc_find_state_file (const gchar *url, if (!key_file) { DEBUG("No key file by that name"); + if (g_strcmp0(sf_extension, STATE_FILE_EXT) == 0) + { + DEBUG("Trying old state file names for compatibility"); + newstyle_filename = filename; + i = 1; + g_free( sf_extension); + sf_extension = g_strdup(""); + continue; + } break; } @@ -252,22 +274,25 @@ gnc_find_state_file (const gchar *url, g_free(file_guid); break; } - else - { - do_increment = TRUE; - } - - DEBUG("Clean up this pass"); g_free(file_guid); g_key_file_free(key_file); g_free(filename); - if (do_increment) - i++; + i++; } DEBUG("Clean up"); g_free(original); + /* Pre-2.4.1 compatibility block: make sure when the state file is + * written again later, it will use the next available filename with + * extension and optional counter. (This name was determined earlier + * in the loop.) */ + if (newstyle_filename) + { + g_free(filename); + filename = newstyle_filename; + } + if (filename_p) *filename_p = filename; else diff --git a/src/app-utils/file-utils.h b/src/app-utils/file-utils.h index 311e9ec5fb..bb975d19b4 100644 --- a/src/app-utils/file-utils.h +++ b/src/app-utils/file-utils.h @@ -95,6 +95,7 @@ gint64 gnc_getline (gchar **line, FILE *file); /* Definitions shared by file-utils.c and gnc-main-window.c */ #define STATE_FILE_TOP "Top" #define STATE_FILE_BOOK_GUID "BookGuid" +#define STATE_FILE_EXT ".gcm" /** Find the state file that corresponds to this URL and guid. *